home *** CD-ROM | disk | FTP | other *** search
/ The Arsenal Files 8 / The Arsenal Files Collection #8 (Arsenal Computer) (1996).ISO / g_quake / ultqsrc.zip / WEAPONS.QC < prev    next >
Text File  |  1996-10-07  |  82KB  |  2,742 lines

  1. void (entity targ, entity inflictor, entity attacker, float damage) T_Damage;
  2. void () player_run;
  3. void(entity bomb, entity attacker, float rad, entity ignore) T_RadiusDamage;
  4. void() W_Precache =
  5. {
  6.     precache_sound2 ("enforcer/enfire.wav");
  7.     precache_sound2 ("enforcer/enfstop.wav");
  8.         precache_model ("progs/laser.mdl"); 
  9.         precache_model ("progs/backpack.mdl");
  10.         precache_model ("progs/shelcase.mdl");
  11.         precache_model ("progs/pipebomb.mdl"); 
  12.         precache_model ("progs/v_pipe.mdl"); 
  13.         precache_model ("progs/g_laser.mdl"); 
  14.         precache_sound ("weapons/warning.wav");
  15.         precache_sound ("weapons/teleeyes.wav");
  16.         precache_sound ("weapons/lhit.wav");
  17.         precache_model ("progs/lavaball.mdl");
  18.         precache_sound ("misc/power.wav");
  19.         precache_sound ("doors/basetry.wav");
  20.         precache_sound ("weapons/flame.wav");  
  21.         precache_sound ("weapons/fbfire.wav"); 
  22.         precache_sound ("weapons/r_exp3.wav");        
  23.         precache_sound ("weapons/rocket1i.wav");        
  24.     precache_sound ("weapons/sgun1.wav");
  25.         precache_sound ("weapons/guncock.wav"); 
  26.         precache_sound ("weapons/ric1.wav");    
  27.         precache_sound ("weapons/ric2.wav");    
  28.         precache_sound ("weapons/ric3.wav");    
  29.         precache_sound ("weapons/spike2.wav");  
  30.         precache_sound ("weapons/tink1.wav");   
  31.         precache_sound ("weapons/grenade.wav"); 
  32.         precache_sound ("weapons/bounce.wav");          
  33.         precache_sound ("weapons/shotgn2.wav"); 
  34.         precache_sound ("weapons/pkup.wav");  
  35.         precache_sound ("weapons/shellhit.wav"); 
  36.         precache_sound ("player/tornoff2.wav");
  37.         precache_sound ("player/slimbrn2.wav");
  38.     precache_sound ("ambience/fire1.wav");
  39.     precache_model ("progs/flame2.mdl");
  40.         precache_sound ("zombie/z_miss.wav");
  41.         precache_sound ("weapons/kick.wav");
  42.         precache_sound ("weapons/slop.wav");
  43.         precache_sound ("weapons/step1.wav");
  44.         precache_sound ("weapons/step2.wav");
  45.         precache_sound ("weapons/step3.wav");
  46.         precache_sound ("weapons/step4.wav");
  47.         precache_sound ("weapons/step5.wav");
  48.         precache_sound ("weapons/step6.wav");
  49.         precache_sound ("weapons/stepstop.wav");
  50.         precache_sound ("demon/ddeath.wav");
  51.         precache_sound ("items/inv3.wav");
  52.         precache_sound ("items/r_item1.wav");
  53.         precache_sound ("items/protect3.wav");
  54.         precache_sound ("weapons/moadib.wav");
  55.         precache_model("progs/throwaxe.mdl");
  56.         precache_model("progs/null.spr");
  57.         precache_sound("weapons/woosh.wav");
  58.         precache_sound("weapons/taxhit1.wav");
  59.         precache_sound("weapons/taxhit2.wav");
  60.         precache_sound("weapons/taxhit3.wav");
  61. };
  62.  
  63.  
  64. /*
  65. ================
  66. W_FireAxe
  67. ================
  68. */
  69. void() W_FireAxe =
  70. {
  71.     local   vector  source;
  72.     local   vector  org;
  73.  
  74.     source = self.origin + '0 0 16';
  75.     traceline (source, source + v_forward*64, FALSE, self);
  76.     if (trace_fraction == 1.0)
  77.         return;
  78.     
  79.     org = trace_endpos - v_forward*4;
  80.  
  81.     if (trace_ent.takedamage)
  82.     {
  83.         trace_ent.axhitme = 1;
  84.         SpawnBlood (org, '0 0 0', 20);
  85.                 sound (self, CHAN_WEAPON, "zombie/z_miss.wav", 1, ATTN_NORM);
  86.         T_Damage (trace_ent, self, self, 20);
  87.     }
  88.     else
  89.         {       
  90.         sound (self, CHAN_WEAPON, "player/axhit2.wav", 1, ATTN_NORM);
  91.         WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  92.         WriteByte (MSG_BROADCAST, TE_GUNSHOT);
  93.         WriteCoord (MSG_BROADCAST, org_x);
  94.         WriteCoord (MSG_BROADCAST, org_y);
  95.         WriteCoord (MSG_BROADCAST, org_z);
  96.     }
  97. };
  98.  
  99. vector() wall_velocity =
  100. {
  101.     local vector    vel;
  102.     
  103.     vel = normalize (self.velocity);
  104.     vel = normalize(vel + v_up*(random()- 0.5) + v_right*(random()- 0.5));
  105.     vel = vel + 2*trace_plane_normal;
  106.     vel = vel * 200;
  107.     
  108.     return vel;
  109. };
  110.  
  111.  
  112. /*
  113. ================
  114. SpawnBlood
  115. ================
  116. */
  117. void(vector org, vector vel, float damage) SpawnBlood =
  118. {
  119.     particle (org, vel*0.1, 73, damage*2);
  120. };
  121.  
  122. /*
  123. ================
  124. spawn_touchblood
  125. ================
  126. */
  127. void(float damage) spawn_touchblood =
  128. {
  129.     local vector    vel;
  130.  
  131.     vel = wall_velocity () * 0.2;
  132.     SpawnBlood (self.origin + vel*0.01, vel, damage);
  133. };
  134.  
  135.  
  136. /*
  137. ================
  138. SpawnChunk
  139. ================
  140. */
  141. void(vector org, vector vel) SpawnChunk =
  142. {
  143.     particle (org, vel*0.02, 0, 10);
  144. };
  145.  
  146. /*
  147. ==============================================================================
  148.  
  149. MULTI-DAMAGE
  150.  
  151. Collects multiple small damages into a single damage
  152.  
  153. ==============================================================================
  154. */
  155.  
  156. entity  multi_ent;
  157. float   multi_damage;
  158.  
  159. void() ClearMultiDamage =
  160. {
  161.     multi_ent = world;
  162.     multi_damage = 0;
  163. };
  164.  
  165. void() ApplyMultiDamage =
  166. {
  167.     if (!multi_ent)
  168.         return;
  169.     T_Damage (multi_ent, self, self, multi_damage);
  170. };
  171.  
  172. void(entity hit, float damage) AddMultiDamage =
  173. {
  174.     if (!hit)
  175.         return;
  176.     
  177.     if (hit != multi_ent)
  178.     {
  179.         ApplyMultiDamage ();
  180.         multi_damage = damage;
  181.         multi_ent = hit;
  182.     }
  183.     else
  184.         multi_damage = multi_damage + damage;
  185. };
  186.  
  187. /*
  188. ==============================================================================
  189.  
  190. BULLETS
  191.  
  192. ==============================================================================
  193. */
  194.  
  195. /*
  196. ================
  197. TraceAttack
  198. ================
  199. */
  200. void(vector org,entity targ) Ricochet =
  201. {
  202. local float r;
  203. WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  204. WriteByte (MSG_BROADCAST, TE_GUNSHOT);
  205. WriteCoord (MSG_BROADCAST, org_x);
  206. WriteCoord (MSG_BROADCAST, org_y);
  207. WriteCoord (MSG_BROADCAST, org_z);
  208.                 r = random()*100;
  209.                 if (r > 95)
  210.                         sound (self,CHAN_AUTO,"weapons/ric1.wav",1,ATTN_NORM);
  211.                 else if (r > 91)
  212.                         sound (self,CHAN_AUTO,"weapons/ric2.wav",1,ATTN_NORM);
  213.                 else if (r > 87)
  214.                         sound (self,CHAN_AUTO,"weapons/ric3.wav",1,ATTN_NORM);
  215.  
  216. };
  217.  
  218. void(float damage, vector dir) TraceAttack =
  219. {
  220.     local   vector  vel, org;
  221.     
  222.     vel = normalize(dir + v_up*crandom() + v_right*crandom());
  223.     vel = vel + 2*trace_plane_normal;
  224.     vel = vel * 200;
  225.  
  226.     org = trace_endpos - dir*4;
  227.  
  228.     if (trace_ent.takedamage)
  229.     {
  230.                 if (trace_ent.reflecttime > time)
  231.                         Ricochet(org,trace_ent);
  232.                 else
  233.                         SpawnBlood (org, vel*0.2, damage);
  234.         AddMultiDamage (trace_ent, damage);
  235.     }
  236.     else
  237.                 Ricochet(org,trace_ent);
  238. };
  239.  
  240. /*
  241. ================
  242. FireBullets
  243.  
  244. Used by shotgun, super shotgun, and enemy soldier firing
  245. Go to the trouble of combining multiple pellets into a single damage call.
  246. ================
  247. */
  248. void(float shotcount, vector dir, vector spread) FireBullets =
  249. {
  250.     local   vector direction;
  251.     local   vector  src;
  252.     
  253.     makevectors(self.v_angle);
  254.  
  255.     src = self.origin + v_forward*10;
  256.     src_z = self.absmin_z + self.size_z * 0.7;
  257.  
  258.     ClearMultiDamage ();
  259.     while (shotcount > 0)
  260.     {
  261.         direction = dir + crandom()*spread_x*v_right + crandom()*spread_y*v_up;
  262.  
  263.         traceline (src, src + direction*2048, FALSE, self);
  264.         if (trace_fraction != 1.0)
  265.             TraceAttack (4, direction);
  266.  
  267.         shotcount = shotcount - 1;
  268.     }
  269.     ApplyMultiDamage ();
  270. };
  271.  
  272. /* Flare */
  273. void() flare_dim =
  274. {
  275.     self.effects=8;
  276.         self.nextthink = time + 10;
  277.     self.think = SUB_Remove;
  278. };
  279. void() FlarePlayerTouch =
  280. {
  281.         self.origin = self.enemy.origin + '0 0 16';
  282.     if (self.velocity == '0 0 0')
  283.         self.avelocity = '0 0 0';
  284. };
  285. void() flare_touch =
  286. {
  287. local float rand;
  288.     if (other == self.owner)
  289.         return;
  290.  
  291.     if (other.solid == SOLID_TRIGGER)
  292.         return; // trigger field, do nothing
  293.  
  294.     if (pointcontents(self.origin) == CONTENT_SKY)
  295.     {
  296.         remove(self);
  297.         return;
  298.     }
  299.     if(other.takedamage == DAMAGE_AIM)
  300.     {
  301.                 spawn_touchblood (2);
  302.                 self.enemy = other;
  303.                 self.origin = other.origin + '0 0 8';
  304.         if (self.effects != EF_DIMLIGHT)
  305.         {
  306.                         sprint (self.owner, "You lit up ");
  307.             if (self.enemy.classname == "player")
  308.             {
  309.                 sprint (self.owner, self.enemy.netname);
  310.                 sprint (self.owner, "!\n");
  311.             
  312.                                 sprint (self.enemy, "You are lit up!");
  313.             }
  314.             else
  315.             {
  316.                 sprint (self.owner, "a ");
  317.                 sprint (self.owner, self.enemy.classname);
  318.                 sprint (self.owner, "!\n");
  319.             }
  320.             self.effects = EF_DIMLIGHT;
  321.                         self.touch = FlarePlayerTouch;
  322.         }
  323.  
  324.     }
  325.        else
  326.        {
  327.         self.movetype = MOVETYPE_NONE;
  328.     self.velocity = '0 0 0';
  329.     self.touch = SUB_Null;
  330.        }
  331. };
  332. /*
  333. ==============================================================================
  334.  
  335. ROCKETS
  336.  
  337. ==============================================================================
  338. */
  339. void() T_SpreadTouch =
  340. {
  341.     local float    damg;
  342.  
  343.     if (other == self.owner)
  344.                 return;         
  345.  
  346.         if(other.classname==self.classname)
  347.                 return;
  348.         
  349.     if (pointcontents(self.origin) == CONTENT_SKY)
  350.     {
  351.         remove(self);
  352.         return;
  353.     }
  354.  
  355.         if (other.reflecttime > time)
  356.               {
  357.               BounceBack(self.owner,other);
  358.               return;
  359.               }
  360.  
  361.         damg = 20 + random()*10;
  362.     
  363.     if (other.health)
  364.     {
  365.         if (other.classname == "monster_shambler")
  366.                         damg = damg * 0.5;      
  367.         T_Damage (other, self, self.owner, damg );
  368.     }
  369.  
  370.         T_RadiusDamage (self, self.owner, 50, other);
  371.  
  372.     self.origin = self.origin - 8*normalize(self.velocity);
  373.  
  374.     WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  375.     WriteByte (MSG_BROADCAST, TE_EXPLOSION);
  376.     WriteCoord (MSG_BROADCAST, self.origin_x);
  377.     WriteCoord (MSG_BROADCAST, self.origin_y);
  378.     WriteCoord (MSG_BROADCAST, self.origin_z);
  379.     BecomeExplosion ();
  380. };
  381.  
  382. /*
  383. Rockets find target
  384. */
  385. entity () HomeFindTarget =
  386. {
  387.         local entity head, selected;
  388.         local float dist;
  389.         dist = 100000;
  390.         selected = world;
  391.         head = findradius(self.origin, 1000);
  392.         while(head)
  393.         {
  394.           if((head.health > 0.1) && (head != self) && (head != self.owner) && !( (teamplay == 1) && (head.team > 0)&&(head.team == self.owner.team) ) && (head.classname != "door") && (head.classname != "misc_explobox") && !(head.items & IT_INVISIBILITY) && (head.beendead != TRUE) && (head.controller != self.owner))
  395.              {
  396.                         if(self.touch == T_SpreadTouch && self.owner == head.owner)
  397.                                 break;
  398.                         else
  399.                         {
  400.                         traceline(self.origin,head.origin,TRUE,self);
  401.                         if ( (trace_fraction >= 1) && (vlen(head.origin - self.origin) < dist) )
  402.                             {
  403.                                 selected = head;
  404.                                 dist = vlen(head.origin - self.origin);
  405.                             }
  406.                         }
  407.                 }
  408.                 head = head.chain;
  409.         }
  410.  
  411.         if (selected != world)   
  412.         {
  413.                 sprint (self.owner,"Homing->");
  414.                 if (selected.classname == "player")
  415.                 {
  416.                         sprint (self.owner,selected.netname);
  417.                         sprint(selected,"Warning!  ");
  418.                         sprint(selected,self.owner.netname);
  419.                         sprint(selected," has a lock on you!\n");
  420.                 }
  421.                 else sprint (self.owner,selected.classname);
  422.                 sprint (self.owner,"\n");
  423.                 sound(self, CHAN_WEAPON, "weapons/warning.wav", 1, ATTN_NORM);
  424.         }
  425.         
  426.         return selected;
  427. };
  428.  
  429. /*
  430. ===============
  431. HomeThink by Vhold
  432. The Think function for the Homing Missile
  433. ===============
  434. */
  435. void() HomeThink =
  436. {
  437.     local vector dir, vtemp;
  438.  
  439.         if (!(self.enemy) || (self.enemy == world) || (self.enemy.health < 0.1) && (self.enemy.beendead != TRUE))
  440.         self.enemy = HomeFindTarget();
  441.  
  442.         if (self.enemy != world) 
  443.     {
  444.         vtemp = self.enemy.origin + '0 0 10';
  445.         dir = normalize(vtemp - self.origin);
  446.                 self.velocity = dir * 350;
  447.                 self.velocity_x = self.velocity_x + (random () * 150 - 75);
  448.                 self.velocity_y = self.velocity_y + (random () * 150 - 75);
  449.                 self.velocity_z = self.velocity_z + (random () * 150 - 75);
  450.         self.angles = vectoangles(self.velocity);
  451.                 if ((self.flags & FL_ONGROUND) && self.follow == 0)
  452.                    {
  453.                    self.flags = self.flags - FL_ONGROUND;
  454.                    self.follow = 1;
  455.                    }
  456.     }
  457.         if (self.alivetime < time && self.classname == "homerocket")
  458.                 remove(self);
  459.         self.nextthink = time + 0.2;
  460.     self.think=HomeThink;
  461. };
  462.  
  463. void()    s_explode1    =    [0,        s_explode2] {};
  464. void()    s_explode2    =    [1,        s_explode3] {};
  465. void()    s_explode3    =    [2,        s_explode4] {};
  466. void()    s_explode4    =    [3,        s_explode5] {};
  467. void()    s_explode5    =    [4,        s_explode6] {};
  468. void()    s_explode6    =    [5,        SUB_Remove] {};
  469.  
  470. void() spike_touch;
  471.  
  472. void() BecomeExplosion =
  473. {
  474.     self.movetype = MOVETYPE_NONE;
  475.     self.velocity = '0 0 0';
  476.     self.touch = SUB_Null;
  477.     setmodel (self, "progs/s_explod.spr");
  478.     self.solid = SOLID_NOT;
  479.     s_explode1 ();
  480. };
  481.  
  482. void() T_MissileTouch =
  483. {
  484.     local float    damg;
  485.  
  486.     if (other == self.owner)
  487.         return;        // don't explode on owner
  488.  
  489.     if (pointcontents(self.origin) == CONTENT_SKY)
  490.     {
  491.         remove(self);
  492.         return;
  493.     }
  494.  
  495.         if (other.reflecttime > time)
  496.               {
  497.               BounceBack(self.owner,other);
  498.               return;
  499.               }
  500.  
  501.     damg = 100 + random()*20;
  502.     
  503.         if (other.health>0&&other.health<99999999)
  504.     {
  505.         if (other.classname == "monster_shambler")
  506.             damg = damg * 0.5;    // mostly immune
  507.         T_Damage (other, self, self.owner, damg );
  508.                 other.velocity_x = other.velocity_x + self.velocity_x;
  509.                 other.velocity_y = other.velocity_y + self.velocity_y;
  510.                 other.velocity_z = other.velocity_z + 100;
  511.                 if(other.flags&FL_ONGROUND)
  512.                         other.flags = other.flags - FL_ONGROUND;
  513.     }
  514.         else if (self.classname == "homerocket")
  515.         {
  516.         sound(self,CHAN_WEAPON,"weapons/pkup.wav",1,ATTN_NORM);
  517.         self.angles = vectoangles ('0 0 0' - self.velocity);
  518.         self.enemy = world;
  519.         self.velocity = '0 0 0';
  520.         self.active = TRUE;
  521.         return;
  522.         }
  523.     // don't do radius damage to the other, because all the damage
  524.     // was done in the impact
  525.     T_RadiusDamage (self, self.owner, 120, other);
  526.  
  527.     self.origin = self.origin - 8*normalize(self.velocity);
  528.  
  529.     WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  530.     WriteByte (MSG_BROADCAST, TE_EXPLOSION);
  531.     WriteCoord (MSG_BROADCAST, self.origin_x);
  532.     WriteCoord (MSG_BROADCAST, self.origin_y);
  533.     WriteCoord (MSG_BROADCAST, self.origin_z);
  534.  
  535.     BecomeExplosion ();
  536. };
  537.  
  538. void() GrenadeExplode =
  539. {
  540.         if(self.classname=="throwaxe")
  541.                 T_RadiusDamage (self, self.owner, 200, world);
  542.         else if(self.owner.classname=="ogre") 
  543.            {
  544.            T_RadiusDamage (self, self.owner, 40, world);
  545.            sound (self, CHAN_VOICE, "weapons/r_exp3.wav", 1, ATTN_NORM);
  546.            }
  547.         else
  548.                 T_RadiusDamage (self, self.owner, 80, world);
  549.  
  550.     WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  551.     WriteByte (MSG_BROADCAST, TE_EXPLOSION);
  552.     WriteCoord (MSG_BROADCAST, self.origin_x);
  553.     WriteCoord (MSG_BROADCAST, self.origin_y);
  554.     WriteCoord (MSG_BROADCAST, self.origin_z);
  555.  
  556.         if(self.owner.classname=="ogre")
  557.         {
  558.                 self.velocity = '0 0 0';
  559.                 self.touch = SUB_Null;
  560.                 setmodel (self, "progs/s_explod.spr");
  561.                 self.solid = SOLID_NOT;
  562.                 s_explode1 ();
  563.         }
  564.         else BecomeExplosion ();
  565. };
  566.  
  567. float(entity targ) visible;
  568. float(entity targ) infront;
  569.  
  570. /*
  571. ================
  572. W_FireRocket
  573. ================
  574. */
  575. void(vector dir,entity cont,string type) W_FireRocket2 =
  576. {
  577.     local   entity missile, mpuff;
  578.     missile = spawn ();
  579.         missile.owner = cont;
  580.         missile.movetype = MOVETYPE_FLYMISSILE;
  581.         missile.solid = SOLID_BBOX;
  582.         missile.health = 10;
  583.         missile.takedamage = DAMAGE_AIM;
  584.         missile.th_die = T_MissileTouch;
  585.         missile.classname = type;
  586.         makevectors (cont.v_angle);
  587.     missile.touch = T_MissileTouch;
  588.  
  589. // set missile speed    
  590.  
  591.         if (type == "homerocket") 
  592.         {
  593.         missile.speed = 350;
  594.         missile.velocity = dir * missile.speed;
  595.         missile.think = HomeThink;
  596.         missile.nextthink = time + 0.2;
  597.     missile.enemy = world;
  598.         missile.controller = self;
  599.         missile.alivetime = time + 180;
  600.         }
  601.         else
  602.         {
  603.         missile.speed = 1000;
  604.         missile.velocity = dir * missile.speed;
  605.     missile.nextthink = time + 5;
  606.     missile.think = SUB_Remove;
  607.         }
  608.     missile.angles = vectoangles(missile.velocity);
  609.  
  610.         setmodel (missile, "progs/missile.mdl");
  611.         setsize (missile, '0 0 0', '0 0 0');            
  612.         setorigin (missile, cont.origin + v_forward*8 + '0 0 16');
  613. };
  614.  
  615. /*
  616. ================
  617. W_FireSpread
  618. ================
  619. */
  620. void() SpreadThink =
  621. {
  622.         self.velocity_x = self.velocity_x + (random() * 100 - 50);
  623.         self.velocity_y = self.velocity_y + (random() * 100 - 50);
  624.         self.velocity_z = self.velocity_z + (random() * 100 - 50);
  625.         self.angles = vectoangles(self.velocity);
  626.         self.nextthink = time + 0.2;
  627.         self.think = SpreadThink;
  628. };
  629.  
  630. void(vector dir,entity cont,string type) W_FireSpread2 =
  631. {
  632.     local    entity missile, mpuff;
  633.  
  634.     missile = spawn ();
  635.     missile.movetype = MOVETYPE_FLYMISSILE;
  636.     missile.solid = SOLID_BBOX;
  637.         missile.owner = cont;
  638.         missile.health = 10;
  639.         missile.takedamage = DAMAGE_AIM;
  640.         missile.th_die = T_SpreadTouch;
  641.         makevectors (cont.v_angle);
  642.         missile.speed = 500;
  643.     missile.nextthink = time + 0.2;
  644.         missile.classname = type;
  645.  
  646.         if (type == "spreadrocket")
  647.         {
  648.         missile.velocity = dir * missile.speed;
  649.         missile.velocity_x = missile.velocity_x + (random() * 100 - 50);
  650.         missile.velocity_y = missile.velocity_y + (random() * 100 - 50);
  651.         missile.velocity_z = missile.velocity_z + (random() * 100 - 50);
  652.         missile.touch = T_SpreadTouch;
  653.         missile.think = SpreadThink;
  654.         }
  655.         else if (type == "homespread")
  656.         {
  657.         missile.velocity = dir * missile.speed;
  658.         missile.velocity_x = missile.velocity_x + (random() * 100 - 50);
  659.         missile.velocity_y = missile.velocity_y + (random() * 100 - 50);
  660.         missile.velocity_z = missile.velocity_z + (random() * 100 - 50);
  661.         missile.touch = T_SpreadTouch;
  662.         missile.think = HomeThink;
  663.         missile.enemy = world;
  664.         }
  665.     missile.angles = vectoangles(missile.velocity);
  666.     setmodel (missile, "progs/missile.mdl");
  667.         setsize (missile, '0 0 0', '0 0 0');
  668.         setorigin (missile, cont.origin + v_forward*8 + '0 0 16');
  669. };
  670.  
  671. void(string type) W_FireSpread =
  672. {
  673. local vector dir;
  674.         dir = aim(self, 1000);
  675.         self.currentammo = self.ammo_rockets = self.ammo_rockets - 1;
  676.     sound (self, CHAN_WEAPON, "weapons/sgun1.wav", 1, ATTN_NORM);
  677.         self.punchangle_x = -5;
  678.         W_FireSpread2(dir,self,type);
  679. };
  680.  
  681. /*
  682. ===============================================================================
  683.  
  684. LIGHTNING
  685.  
  686. ===============================================================================
  687. */
  688.  
  689. /*
  690. =================
  691. LightningDamage
  692. =================
  693. */
  694.  
  695. void (vector endpos) ThroughWaterZap =
  696. {
  697. local entity waterloser;
  698.                 waterloser = spawn();        
  699.                 setorigin (waterloser, endpos);
  700.                 T_RadiusDamageWater (waterloser, waterloser, self);
  701.                 remove (waterloser);
  702. };
  703.  
  704. void (vector startpos) ThroughWater =
  705. {
  706. local vector endpos;
  707. local float mover;
  708.         mover = 600;
  709.         while (mover)
  710.         {
  711.         mover = mover - 25;
  712.         endpos = startpos + v_forward * mover;
  713.         if (pointcontents(endpos) == CONTENT_WATER || pointcontents(endpos) == CONTENT_SLIME)
  714.                 ThroughWaterZap(endpos);
  715.         else if (pointcontents(endpos) == CONTENT_SOLID)
  716.                 return;
  717.         }
  718. };
  719.  
  720. void(vector p1, vector p2, entity from, float damage) LightningDamage =
  721. {
  722.         local entity            e1, e2, swap;
  723.     local vector            f;
  724.         local float             absorb;
  725.     f = p2 - p1;
  726.     normalize (f);
  727.     f_x = 0 - f_y;
  728.     f_y = f_x;
  729.     f_z = 0;
  730.     f = f*16;
  731.  
  732.     e1 = e2 = world;
  733.  
  734.     traceline (p1, p2, FALSE, self);
  735.  
  736.         if (self.classname == "spell")
  737.                 trace_ent = self.enemy;
  738.  
  739.         if (pointcontents(trace_endpos) == CONTENT_WATER || pointcontents(trace_endpos) == CONTENT_SLIME)
  740.                 ThroughWaterZap(trace_endpos);
  741.         else if (trace_ent.watertype == CONTENT_WATER || trace_ent.watertype == CONTENT_SLIME)
  742.                 T_RadiusDamageWater (trace_ent, trace_ent, self);
  743.         else if (trace_ent.takedamage)
  744.     {
  745.         particle (trace_endpos, '0 0 100', 225, damage*4);
  746.                 if (trace_ent.reflecttime > time)
  747.                         {
  748.                         if (from.reflecttime > time)
  749.                                 return;
  750.                         else {
  751.                              swap = from;
  752.                              from = trace_ent;
  753.                              trace_ent = swap;
  754.                              }
  755.                         }
  756.                 if (from.classname == "shambler")
  757.                         {
  758.                         if(trace_ent.prottime < time)
  759.                                 T_Damage (trace_ent, from, from, damage);
  760.                         }
  761.                 else T_Damage (trace_ent, from, from, damage);
  762.         if (self.classname == "player")
  763.                         if (trace_ent.classname == "player")
  764.                                 trace_ent.velocity_z = trace_ent.velocity_z + 400;
  765.     }
  766.         else ThroughWater(p1);
  767.  
  768.         e1 = trace_ent;
  769.     traceline (p1 + f, p2 + f, FALSE, self);
  770.         if (trace_ent != e1 && trace_ent.takedamage)
  771.     {
  772.         particle (trace_endpos, '0 0 100', 225, damage*4);
  773.                 if (trace_ent.reflecttime > time)
  774.                         {
  775.                         if (from.reflecttime > time)
  776.                                 return;
  777.                         else swap = trace_ent;
  778.                              from = trace_ent;
  779.                              trace_ent = swap;
  780.                         }
  781.                 T_Damage (trace_ent, from, from, damage);
  782.     }
  783.     e2 = trace_ent;
  784.     traceline (p1 - f, p2 - f, FALSE, self);
  785.         if (trace_ent != e1 && trace_ent != e2 && trace_ent.takedamage)
  786.     {
  787.         particle (trace_endpos, '0 0 100', 225, damage*4);
  788.                 if (trace_ent.reflecttime > time)
  789.                         {
  790.                         if (from.reflecttime > time)
  791.                                 return;
  792.                         else swap = trace_ent;
  793.                              from = trace_ent;
  794.                              trace_ent = swap;
  795.                         }
  796.                 T_Damage (trace_ent, from, from, damage);
  797.     }
  798. };
  799.  
  800.  
  801. void(entity loser,vector dir) W_FireLightning =
  802. {
  803.     local   vector          org;
  804.  
  805.      if (self.aflag != 33)
  806.      {
  807.     if (self.ammo_cells < 1)
  808.     {
  809.         self.weapon = W_BestWeapon ();
  810.         W_SetCurrentAmmo ();
  811.         return;
  812.     }
  813.  
  814. // explode if under water
  815.     if (self.waterlevel > 1)
  816.     {
  817.         T_RadiusDamage (self, self, 35*self.ammo_cells, world);
  818.         self.ammo_cells = 0;
  819.         W_SetCurrentAmmo ();
  820.         return;
  821.     }
  822.     self.punchangle_x = -2;
  823.  
  824.     self.currentammo = self.ammo_cells = self.ammo_cells - 1;
  825.  
  826.     org = self.origin + '0 0 16';
  827.     
  828.     traceline (org, org + v_forward*600, TRUE, self);
  829.  
  830.      }
  831.      else org = dir;
  832.  
  833.     if (self.t_width < time)
  834.     {
  835.         sound (self, CHAN_WEAPON, "weapons/lhit.wav", 1, ATTN_NORM);
  836.         self.t_width = time + 0.6;
  837.     }
  838.  
  839.     WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  840.     WriteByte (MSG_BROADCAST, TE_LIGHTNING2);
  841.     WriteEntity (MSG_BROADCAST, self);
  842.     WriteCoord (MSG_BROADCAST, org_x);
  843.     WriteCoord (MSG_BROADCAST, org_y);
  844.     WriteCoord (MSG_BROADCAST, org_z);
  845.     WriteCoord (MSG_BROADCAST, trace_endpos_x);
  846.     WriteCoord (MSG_BROADCAST, trace_endpos_y);
  847.     WriteCoord (MSG_BROADCAST, trace_endpos_z);
  848.  
  849.    if (self.aflag != 33)
  850.     LightningDamage (self.origin, trace_endpos + v_forward*4, self, 30);
  851.    else
  852.         LightningDamage (self.origin, dir, self, 30);
  853.  
  854. };
  855.  
  856.  
  857. //=============================================================================
  858. void() GrenadeTouch =
  859. {
  860.     if (other == self.owner)
  861.         return;         // don't explode on owner
  862.         if (other.reflecttime > time)
  863.               {
  864.               GrenBounceBack(self.owner,other,self.speed);
  865.               return;
  866.               }
  867.  
  868.     if (other.takedamage == DAMAGE_AIM)
  869.     {
  870.                 GrenadeExplode();
  871.         return;
  872.     }
  873.     sound (self, CHAN_WEAPON, "weapons/bounce.wav", 1, ATTN_NORM);  // bounce sound
  874.     if (self.velocity == '0 0 0')
  875.         self.avelocity = '0 0 0';
  876. };
  877. //=============================================================================
  878.  
  879. void() spike_touch =
  880. {
  881. local float multiplier;
  882.     if (other == self.owner)
  883.         return;
  884.  
  885.     if (other.solid == SOLID_TRIGGER)
  886.         return; // trigger field, do nothing
  887.  
  888.     if (pointcontents(self.origin) == CONTENT_SKY)
  889.     {
  890.         remove(self);
  891.         return;
  892.     }
  893.  
  894.         if (other.reflecttime > time)
  895.         {
  896.               BounceBack(self.owner,other);
  897.               return;
  898.         }
  899.  
  900. // hit something that bleeds
  901.  
  902.         if (other.takedamage)
  903.     {
  904.                 if (self.classname == "superspike")
  905.                         multiplier = 2;
  906.                 else if (self.classname == "shrapnel"||self.classname == "blades")
  907.                         multiplier = 4;
  908.                 else if (self.classname == "spike" || self.classname == "wizspike" || self.classname == "knightspike")
  909.                         multiplier = 1;
  910.                 else if (other.prottime > time)
  911.                         multiplier = 0;
  912.                 
  913.                 spawn_touchblood (9*multiplier);
  914.                 T_Damage (other, self, self.owner, 9*multiplier);
  915.     }
  916.         else
  917.     {
  918.         WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  919.         
  920.         if (self.classname == "wizspike")
  921.             WriteByte (MSG_BROADCAST, TE_WIZSPIKE);
  922.         else if (self.classname == "knightspike")
  923.             WriteByte (MSG_BROADCAST, TE_KNIGHTSPIKE);
  924.                 else if (self.classname == "spike")
  925.             WriteByte (MSG_BROADCAST, TE_SPIKE);
  926.                 else    WriteByte (MSG_BROADCAST, TE_SUPERSPIKE);
  927.  
  928.         WriteCoord (MSG_BROADCAST, self.origin_x);
  929.         WriteCoord (MSG_BROADCAST, self.origin_y);
  930.         WriteCoord (MSG_BROADCAST, self.origin_z);
  931.     }
  932.     remove(self);
  933. };
  934.  
  935. /*
  936. ===============
  937. launch_spike
  938.  
  939. Used for the player and the wiz & hknight
  940. ===============
  941. */
  942. void(vector org,vector dir, entity cont,string type,float ox) launch_spike =
  943. {
  944.     newmis = spawn ();
  945.         newmis.owner = cont;
  946.     newmis.movetype = MOVETYPE_FLYMISSILE;
  947.     newmis.solid = SOLID_BBOX;
  948.  
  949.     newmis.angles = vectoangles(dir);
  950.     
  951.     newmis.touch = spike_touch;
  952.         newmis.classname = type;
  953.     newmis.think = SUB_Remove;
  954.     newmis.nextthink = time + 6;
  955.         if (type == "shrapnel")
  956.                 newmis.speed = 1400;
  957.         else if (type == "knightspike")
  958.                 {
  959.                 newmis.speed = 300;
  960.                 setmodel (newmis, "progs/k_spike.mdl");
  961.                 }
  962.         else if (type == "wizspike")
  963.                 {
  964.                 newmis.speed = 600;
  965.         setmodel (newmis, "progs/w_spike.mdl");
  966.                 }
  967.         else newmis.speed = 1000;
  968.  
  969.         if (type == "spike")
  970.                 setmodel (newmis, "progs/spike.mdl");
  971.         else if (type != "wizspike" && type != "knightspike")
  972.                 setmodel (newmis, "progs/s_spike.mdl");
  973.  
  974.         setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);
  975.         if (type == "spike")
  976.                 setorigin (newmis, org + '0 0 16' + v_right*ox);
  977.         else if (type == "superspike")       
  978.                 setorigin (newmis, org + '0 0 16');
  979.         else setorigin (newmis, org);
  980.         newmis.velocity = dir * newmis.speed;
  981. };
  982.  
  983. void(float ox) W_FireSpikes =
  984. {
  985.     local vector    dir;
  986.         local string type;
  987.     
  988.     makevectors (self.v_angle);
  989.     dir = aim (self, 1000);
  990.     if (self.ammo_nails < 1)
  991.     {
  992.         self.weapon = W_BestWeapon ();
  993.         W_SetCurrentAmmo ();
  994.         return;
  995.     }
  996.     self.attack_finished = time + 0.2;
  997.     self.punchangle_x = -2;
  998.     if (self.ammo_nails >= 2 && self.weapon == IT_SUPER_NAILGUN)
  999.     {
  1000.     sound (self, CHAN_WEAPON, "weapons/spike2.wav", 1, ATTN_NORM);
  1001.         self.currentammo = self.ammo_nails = self.ammo_nails - 2;
  1002.         type = "superspike";
  1003.         launch_spike(self.origin,dir,self,type,0);
  1004.         }
  1005.         else
  1006.         {
  1007.     sound (self, CHAN_WEAPON, "weapons/rocket1i.wav", 1, ATTN_NORM);
  1008.         self.currentammo = self.ammo_nails = self.ammo_nails - 1;
  1009.         type = "spike";
  1010.         launch_spike(self.origin,dir,self,type,ox);
  1011.         }
  1012. };
  1013.  
  1014.  
  1015. void () FireDie =
  1016. {
  1017.         T_RadiusDamage (self, self.owner, (self.mass - 1)*125+25, world);
  1018.  
  1019.     self.origin = self.origin - 8*normalize(self.velocity);
  1020.  
  1021.     WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  1022.     WriteByte (MSG_BROADCAST, TE_EXPLOSION);
  1023.     WriteCoord (MSG_BROADCAST, self.origin_x);
  1024.     WriteCoord (MSG_BROADCAST, self.origin_y);
  1025.     WriteCoord (MSG_BROADCAST, self.origin_z);
  1026.  
  1027.     BecomeExplosion ();
  1028.         remove(self);
  1029. };
  1030.  
  1031. void() FireDamage =
  1032. {
  1033.         local entity loser;
  1034.         local float marked;
  1035.  
  1036.     self.wait = self.wait - 1;
  1037.         if(self.classname == "fire")
  1038.                 loser = self.enemy;
  1039.         else loser = self.trigger_field;
  1040.  
  1041.         loser.effects = 4;
  1042.  
  1043.         if (loser.classname == "player" && self.owner.classname != "player")
  1044.                 self.owner = loser;
  1045.  
  1046.         if (loser.waterlevel > 2 && loser.watertype != CONTENT_LAVA)
  1047.             {    
  1048.             sound (self.owner, CHAN_WEAPON, "player/slimbrn2.wav", 1, ATTN_NORM);
  1049.             sprint(self.owner,loser.netname);
  1050.             sprint(self.owner," saved his ass by jumping in the water!\n");
  1051.             loser.effects = 0;
  1052.             remove(self);
  1053.             }
  1054.  
  1055.         if (loser.waterlevel > 2 && loser.watertype == CONTENT_LAVA)
  1056.             {    
  1057.             sprint(self.owner,loser.netname);
  1058.             sprint(self.owner," jumped out of the frying pan into the fire!\n");
  1059.             loser.effects = 0;
  1060.             FireDie();
  1061.             }
  1062.                 
  1063.        if ((self.waterlevel > 2) || (self.watertype == CONTENT_WATER) || (self.watertype == CONTENT_SLIME) || (pointcontents(self.origin) == CONTENT_WATER) || (pointcontents(self.origin) == CONTENT_SLIME))
  1064.             {
  1065.             sound (self.owner, CHAN_WEAPON, "player/slimbrn2.wav", 1, ATTN_NORM);
  1066.             sprint(self.owner,"Fireball fizzled underwater\n");
  1067.             loser.effects = 0;
  1068.             remove(self);
  1069.             }
  1070.  
  1071.  
  1072.         if (self.active != 5)
  1073.                 {
  1074.                 if ((self.wait < 1) || (loser.health<=0))
  1075.                         {
  1076.                         loser.effects = 0;
  1077.                         remove(self);
  1078.                         }
  1079.                 }
  1080.         else if (self.wait < 1 || loser.health <= 6)
  1081.                 {
  1082.                 self.mass = 2;
  1083.                 loser.effects = 0;
  1084.                 FireDie();
  1085.                 }
  1086.  
  1087.         if (loser.firesistime < time)
  1088.                 {
  1089.                 T_Damage (loser, self, self.owner, self.active*(self.enemy.onfire + 1));
  1090.                 spawn_touchblood(random()*10);
  1091.                 }
  1092.         SpawnFlame (self.origin);
  1093.  
  1094.         self.origin = loser.origin + '0 0 6';
  1095.     self.nextthink = time + 0.05;
  1096.         self.think = FireDamage;
  1097. };
  1098.  
  1099. void() FireTouch =
  1100. {
  1101.     local float     damg;
  1102.  
  1103.     if (other == self.owner)
  1104.         return;         // don't explode on owner
  1105.  
  1106.     if (pointcontents(self.origin) == CONTENT_SKY)
  1107.     {
  1108.         remove(self);
  1109.         return;
  1110.     }
  1111.  
  1112.         
  1113.         if (other.reflecttime > time)
  1114.               {
  1115.               GrenBounceBack(self.owner,other,self.speed);
  1116.               return;
  1117.               }
  1118.  
  1119.         if (other.takedamage)
  1120.     {
  1121.                 sound (self, CHAN_WEAPON, "weapons/flame.wav", 1, ATTN_NORM);
  1122.         self.trigger_field = other;
  1123.                 if(self.classname=="axeflame")
  1124.                         other=self.enemy;
  1125.                 self.origin = other.origin + '0 0 6';
  1126.  
  1127.                 if (other.classname == "player" || self.active == 5)
  1128.                         self.wait = 180;
  1129.                 else
  1130.                         self.wait = 40;
  1131.                 
  1132.                 setsize (self, '0 0 0', '0 0 0');            
  1133.  
  1134.         self.nextthink = time + 0.05;
  1135.                 self.think = FireDamage;
  1136.         self.movetype = MOVETYPE_NOCLIP;
  1137.         self.velocity = '0 0 0' ;
  1138.         self.avelocity = '0 0 1000';
  1139.                 if ((other.waterlevel < 2) && (other.classname == "player"))
  1140.                 sprint(other, "You're burning up!\n");
  1141.         return;
  1142.     }
  1143.         else if (self.movetype == MOVETYPE_FLYMISSILE)
  1144.                 FireDie();
  1145.         sound (self, CHAN_WEAPON, "weapons/flame.wav", 0.75, ATTN_STATIC);  // bounce sound
  1146.         spawn_touchblood (10);
  1147.         SpawnFlame (self.origin);
  1148.     if (self.velocity == '0 0 0')
  1149.         self.avelocity = '0 0 0';
  1150.         if (self.active == 5)
  1151.                 {
  1152.         self.nextthink = time + 0.05;
  1153.                 self.think = FireDamage;
  1154.                 }
  1155. };
  1156.  
  1157. void () FireThink =
  1158. {
  1159.         if ((self.waterlevel > 2) || (self.watertype == CONTENT_WATER) || (self.watertype == CONTENT_SLIME))
  1160.                 {
  1161.                 sound (self.owner, CHAN_WEAPON, "player/slimbrn2.wav", 1, ATTN_NORM);
  1162.                 sprint(self.owner,"Fireball fizzled underwater\n");
  1163.                 remove(self);
  1164.                 }
  1165. if(self.classname=="axeflame")self.origin=self.enemy.origin;
  1166. self.alivetime = self.alivetime + 0.1;
  1167. if (self.alivetime > 5)
  1168.         FireDie();
  1169. self.nextthink = time + 0.1;
  1170. self.think = FireThink;
  1171. };
  1172.  
  1173. void(vector org) SpawnFlame =
  1174. {
  1175. if(pointcontents(self.origin)<-2)
  1176.         return;
  1177. if(self.classname == "axhit")
  1178. {
  1179. local   entity fire;
  1180.         if (pointcontents(self.origin) < -2)
  1181.         {
  1182.                 sound (self, CHAN_WEAPON, "player/slimbrn2.wav", 1, ATTN_NORM);
  1183.                 return;
  1184.         }
  1185.         sound (self, CHAN_WEAPON, "weapons/fbfire.wav", 1, ATTN_NORM);
  1186.         fire = spawn ();
  1187.         fire.owner = self.controller;
  1188.         fire.controller = self;
  1189.         fire.movetype = MOVETYPE_FLYMISSILE;
  1190.         fire.solid = SOLID_BBOX;
  1191.         fire.classname = "axeflame";
  1192.         fire.mass = 1;
  1193.         fire.active = 0.25;
  1194.         fire.avelocity = '300 300 300';
  1195.         fire.touch = FireTouch;
  1196.         fire.nextthink = time + 0.1;
  1197.         fire.think = FireThink;
  1198.         fire.enemy = self.enemy;
  1199.         setmodel (fire, "progs/null.spr");
  1200.         setsize (fire, '0 0 0', '0 0 0');        
  1201.         setorigin (fire, self.enemy.origin);
  1202. }
  1203. else
  1204. {
  1205. local entity    fireflame;
  1206. local float     xorg, yorg, zorg;
  1207.         fireflame = spawn();
  1208.         setmodel (fireflame, "progs/flame2.mdl");
  1209.         fireflame.movetype = MOVETYPE_FLY;
  1210.         fireflame.solid = SOLID_NOT;
  1211.         fireflame.classname = "missile";
  1212.         fireflame.frame = random() * 10;
  1213.         setsize (fireflame, '-2 -2 -2', '1 1 1');
  1214.         xorg = random() * 30 - 15;
  1215.         yorg = random() * 30 - 15;
  1216.         zorg = random() * 50 - 25;
  1217.         setorigin (fireflame, org + v_forward * xorg + v_right * yorg + v_up * zorg);
  1218.         fireflame.velocity_x = fireflame.velocity_x + (80 * random() - 40);
  1219.         fireflame.velocity_y = fireflame.velocity_y + (80 * random() - 40);
  1220.         fireflame.velocity_z = fireflame.velocity_z + 300 * random();
  1221.         fireflame.avelocity = '0 0 0';
  1222.         if (random() < 0.3)
  1223.                 sound (self, CHAN_WEAPON, "weapons/flame.wav", 1, ATTN_NORM);
  1224.         fireflame.nextthink = time + 0.5;    // remove after half second
  1225.         fireflame.think = SUB_Remove;
  1226. }
  1227. };
  1228.  
  1229. /*
  1230. ================
  1231. FireBall  
  1232. ================
  1233. */
  1234. void(float type,vector offset) FireBall =
  1235. {
  1236.     local   entity missile, mpuff;
  1237.     
  1238.         if (self.currentammo < 2&&type!=2)
  1239.     {
  1240.                 sprint(self,"A fireball requires 2 shells\n");
  1241.                 return;
  1242.     }
  1243.         if (self.waterlevel > 2)
  1244.         {
  1245.                 sound (self, CHAN_WEAPON, "player/slimbrn2.wav", 1, ATTN_NORM);
  1246.                 sprint(self,"Fireball fizzled underwater\n");
  1247.                 if(type!=2)
  1248.                         self.currentammo = self.ammo_shells = self.ammo_shells - 2;
  1249.                 return;
  1250.         }
  1251.  
  1252.     
  1253.         sound (self, CHAN_WEAPON, "weapons/fbfire.wav", 1, ATTN_NORM);
  1254.  
  1255.         self.punchangle_x = -3;
  1256.  
  1257.  
  1258.     missile = spawn ();
  1259.         missile.owner = self;
  1260.         missile.mass = type;
  1261.         if (type == 2)
  1262.                 {
  1263.                 missile.movetype = MOVETYPE_FLYMISSILE;
  1264.                 self.mass = 1;
  1265.                 }
  1266.         else
  1267.                 {
  1268.                 missile.movetype = MOVETYPE_BOUNCE;
  1269.                 self.currentammo = self.ammo_shells = self.ammo_shells - 2;
  1270.                 }
  1271.     missile.solid = SOLID_BBOX;
  1272.         missile.classname = "grenade";
  1273.         missile.effects = 8;
  1274.         missile.health = 10;
  1275.         missile.takedamage = DAMAGE_AIM;
  1276.         missile.th_die = FireDie;
  1277.         missile.active = 0.25;
  1278.  
  1279. // set missile speed
  1280.  
  1281.  
  1282.     makevectors (self.v_angle);
  1283.         missile.speed = 600;
  1284.     if (self.v_angle_x)
  1285.                 missile.velocity = v_forward*1000 + v_up * ((2-type)*100);
  1286.     else
  1287.     {
  1288.         missile.velocity = aim(self, 10000);
  1289.                 missile.velocity = missile.velocity * missile.speed;
  1290.                 missile.velocity_z = ((2-type)*100);
  1291.     }
  1292.  
  1293.     missile.avelocity = '300 300 300';
  1294.  
  1295.     missile.angles = vectoangles(missile.velocity);
  1296.     
  1297.         missile.touch = FireTouch;
  1298.     
  1299. // set missile duration
  1300.         missile.nextthink = time + 0.1;
  1301.         missile.think = FireThink;
  1302.         setmodel (missile, "progs/lavaball.mdl");
  1303.         setsize (missile, '0 0 0', '0 0 0');        
  1304.         setorigin (missile, self.origin + v_forward*8 + '0 0 16' + offset);
  1305. };
  1306.  
  1307. /*
  1308.  ------------------------------------------
  1309.  Pipe Bombs
  1310.  ------------------------------------------
  1311. */
  1312.  
  1313. /*
  1314.  * Blow up the toys.  There is a range of 10000 units (pixels?), so you can't
  1315.  * go wandering off.
  1316.  */
  1317.  
  1318. void() DetPipeBombs =
  1319. {
  1320.     local entity    head;
  1321.  
  1322.     head = findradius (self.origin, 10000);
  1323.     while(head)
  1324.     {
  1325.                 if((head.classname == "grenade" || head.classname == "homerocket") && (head.owner == self) && (head.active == TRUE))
  1326.         {
  1327.             head.think = GrenadeExplode;
  1328.             head.nextthink = time;
  1329.         }
  1330.         head = head.chain;
  1331.     }
  1332. };
  1333.  
  1334. /*
  1335.  * What happens if it touches something
  1336.  */
  1337. void() TaggedPBTouch =  
  1338. {
  1339.         
  1340.     self.origin = self.enemy.origin;
  1341.     if (self.velocity == '0 0 0')
  1342.         self.avelocity = '0 0 0';
  1343. };
  1344. void() PipeBombTouch =
  1345. {
  1346.         if (other == self.owner)
  1347.         return;         // don't explode on owner
  1348.  
  1349.         if (other.owner == self.owner)
  1350.                 return;         // don't tag owner's stuff
  1351.  
  1352.         
  1353.         if (other.reflecttime > time)
  1354.               {
  1355.               GrenBounceBack(self.owner,other,self.speed);
  1356.               return;
  1357.               }
  1358.  
  1359.  
  1360.         if(other.takedamage == DAMAGE_AIM || other.classname == "zombie")
  1361.     {
  1362.         if(!self.enemy)
  1363.         {
  1364.             sound(self, CHAN_WEAPON, "weapons/tink1.wav", 1, ATTN_NORM);
  1365.             self.think = GrenadeExplode;
  1366.         }
  1367.  
  1368.         self.enemy = other;
  1369.         self.origin = self.enemy.origin;
  1370.         if (self.effects != EF_DIMLIGHT)
  1371.         {
  1372.             sprint (self.owner, "You have tagged ");
  1373.             if (self.enemy.classname == "player")
  1374.             {
  1375.                 sprint (self.owner, self.enemy.netname);
  1376.                 sprint (self.owner, "!\n");
  1377.             
  1378.                 sprint (self.enemy, "You have been tagged by ");
  1379.                 sprint (self.enemy, self.owner.netname);
  1380.                 sprint (self.enemy, "!!!\n");
  1381.             }
  1382.             else
  1383.             {
  1384.                 sprint (self.owner, "a ");
  1385.                                 if (self.enemy.frommonname)
  1386.                                        {
  1387.                                         sprint (self.owner," ");
  1388.                                         sprint (self.owner,trace_ent.frommonname);
  1389.                                         sprint (self.owner," ");
  1390.                                         }
  1391.                 sprint (self.owner, self.enemy.classname);
  1392.                 sprint (self.owner, "!\n");
  1393.                                 if (self.enemy.classname == "TeleEye")
  1394.                                         {
  1395.                                         sprint (self.enemy.owner, "You're TeleEye has been tagged!!!\n");
  1396.                                         sound(self.enemy.owner, CHAN_WEAPON, "weapons/warning.wav", 1, ATTN_NORM);
  1397.                                         }
  1398.             }
  1399.             self.effects = EF_DIMLIGHT;
  1400.             self.think = TaggedPBTouch;
  1401.             self.touch = TaggedPBTouch;
  1402.             self.nextthink = time;
  1403.         }
  1404.  
  1405.     }
  1406.  
  1407.     sound (self, CHAN_WEAPON, "weapons/bounce.wav", 1, ATTN_NORM);  // bounce sound
  1408.     if (self.velocity == '0 0 0')
  1409.         self.avelocity = '0 0 0';
  1410.  
  1411. };
  1412.  
  1413. /*
  1414.  * Fires a pipe bomb.  Can be detonated at any time.  Doesn't need a special
  1415.  * weapon selected.
  1416.  */
  1417.  
  1418.  
  1419. void() DisarmPipeBombs =
  1420. {
  1421.     // code for making all tagged pipebombs within radius disappear
  1422.     local entity    head;
  1423.  
  1424.     head = findradius (self.origin, 10000);
  1425.  
  1426.     while(head)
  1427.     {
  1428.                 if((head.classname == "grenade") && (head.owner == self) && (head.active == TRUE))
  1429.         {
  1430.             // Hmmm. Wonder if this works...
  1431.             // Notify owner
  1432.             if (head.enemy.classname == "player")
  1433.             {
  1434.                                 sprint (self,"You have spared ");
  1435.                 sprint (self,head.enemy.netname);
  1436.                 sprint (self,"!..  Why?!?\n");
  1437.                 sprint (head.enemy,"Your miserable life has been spared by ");
  1438.                 sprint (head.enemy,self.netname);
  1439.                 sprint (head.enemy,".\n");
  1440.             }
  1441.                         else if (head.enemy.classname != "worldspawn")
  1442.             {
  1443.                                 sprint (self,"You have spared ");
  1444.                 sprint (self, "a ");
  1445.                                         if (trace_ent.frommonname)
  1446.                                                 {
  1447.                                                 sprint (self," ");
  1448.                                                 sprint (self,trace_ent.frommonname);
  1449.                                                 sprint (self," ");
  1450.                                                 }
  1451.                 sprint (self, head.enemy.classname);
  1452.                 sprint (self,"!..  Why?!?\n");
  1453.             }
  1454.                         else
  1455.                                 {
  1456.                                 head.active = FALSE;
  1457.                                 head.nextthink = time;
  1458.                                 head.think = item_disarmedpipe;
  1459.                                 return;
  1460.                                 }
  1461.                         spawn_tfog (head.origin);
  1462.                         sound(head,CHAN_VOICE,"misc/r_tele2.wav",1,ATTN_NORM);
  1463.                         sound(head.owner,CHAN_ITEM,"weapons/pkup.wav",1,ATTN_NORM);
  1464.                         head.owner.ammo_rockets = head.owner.ammo_rockets + 1;
  1465.             head.movetype = MOVETYPE_NONE;
  1466.             head.velocity = '0 0 0';
  1467.             head.touch = SUB_Null;
  1468.             head.think = SUB_Remove;
  1469.             head.nextthink = time;
  1470.         }
  1471.         head = head.chain;
  1472.     }
  1473.         return;
  1474. };
  1475. /*
  1476. ================
  1477. W_FireGrenade
  1478. ================
  1479. */
  1480. void() W_FireGrenade =
  1481. {
  1482.     local   entity missile, mpuff;
  1483.         self.currentammo = self.ammo_rockets = self.ammo_rockets - 1;
  1484.         sound (self, CHAN_WEAPON, "weapons/grenade.wav", 1, ATTN_NORM);
  1485.  
  1486.     self.punchangle_x = -2;
  1487.  
  1488.     missile = spawn ();
  1489.         missile.takedamage = DAMAGE_AIM;
  1490.         missile.th_die = GrenadeExplode;
  1491.         missile.health = 10;
  1492.     missile.owner = self;
  1493.     missile.movetype = MOVETYPE_BOUNCE;
  1494.         missile.solid = SOLID_BBOX;
  1495.     missile.classname = "grenade";
  1496.  
  1497.     if(self.weapon == IT_PIPE_LAUNCHER)
  1498.         {
  1499.         setsize (missile, '-3 -3 -3', '3 3 3');
  1500.         missile.beendead = TRUE;
  1501.         missile.active = TRUE; 
  1502.     missile.touch = PipeBombTouch;
  1503.     missile.think = GrenadeExplode;
  1504.         setmodel (missile, "progs/pipebomb.mdl");
  1505.         }
  1506.    else
  1507.         {
  1508.     setmodel (missile, "progs/grenade.mdl");
  1509.     missile.touch = GrenadeTouch;
  1510.         missile.nextthink = time + 2.5;
  1511.     missile.think = GrenadeExplode;
  1512.         setsize (missile, '0 0 0', '0 0 0');            
  1513.         }
  1514.  
  1515.     makevectors (self.v_angle);
  1516.  
  1517.         missile.speed = 600;
  1518.     if (self.v_angle_x)
  1519.         missile.velocity = v_forward*600 + v_up * 200 + crandom()*v_right*10 + crandom()*v_up*10;
  1520.     else
  1521.     {
  1522.         missile.velocity = aim(self, 10000);
  1523.         missile.velocity = missile.velocity * 600;
  1524.         missile.velocity_z = 200;
  1525.     }
  1526.  
  1527.     missile.avelocity = '300 300 300';
  1528.  
  1529.     missile.angles = vectoangles(missile.velocity);
  1530.         setorigin (missile, self.origin);
  1531. };
  1532.  
  1533. /*
  1534. =====================
  1535. LASER STUFF -- Shyft
  1536. =====================
  1537. */
  1538.  
  1539. void() Laser_Touch; //Enforcer.qc Laser_touch() modified to change player dmg
  1540.  
  1541. void(vector dir, entity cont) PLaser = 
  1542. {
  1543.     newmis = spawn();
  1544.         newmis.owner = cont;
  1545.     newmis.movetype = MOVETYPE_FLY;
  1546.     newmis.solid = SOLID_BBOX;
  1547.     newmis.effects = EF_DIMLIGHT;
  1548.         newmis.classname = "laser";
  1549.         makevectors (cont.v_angle);
  1550.  
  1551.     setmodel (newmis, "progs/laser.mdl");
  1552.  
  1553.         if (cont.classname != "player")
  1554.         {
  1555.     setsize (newmis, '0 0 0', '0 0 0');
  1556.         setorigin (newmis, cont.origin);
  1557.         }
  1558.         else
  1559.         {
  1560.         setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);
  1561.         setorigin (newmis, cont.origin + v_forward*8 + '0 0 16');
  1562.         }
  1563.  
  1564.         newmis.speed = 600;
  1565.         newmis.velocity = dir * newmis.speed;
  1566.  
  1567.         newmis.angles = vectoangles(newmis.velocity);
  1568.  
  1569.     newmis.nextthink = time + 5;
  1570.     newmis.think = SUB_Remove;
  1571.         newmis.touch = Laser_Touch;
  1572. };
  1573. /*
  1574. ===============================================================================
  1575.  
  1576. PLAYER WEAPON USE
  1577.  
  1578. ===============================================================================
  1579. */
  1580.  
  1581. void() Duck =
  1582. {
  1583.         if (self.ducking)
  1584.         {
  1585.     setsize (self, VEC_HULL_MIN, VEC_HULL_MAX);
  1586.         self.view_ofs = '0 0 22';
  1587.         self.ducking = FALSE;
  1588.         centerprint (self, "Standing\n");
  1589.         player_stand1();
  1590.         }
  1591.         else
  1592.         {
  1593.         setsize (self , '-16 -16 -24' , '16 16 4');      // change bounding bos so you're shorter
  1594.         self.view_ofs = '0 0 4';
  1595.         self.ducking = time + 0.3;
  1596.         player_duck1();
  1597.         centerprint (self, "Ducking\n");
  1598.         }
  1599. };
  1600.  
  1601. void() W_SetCurrentAmmo =
  1602. {
  1603.  if(self.classname != "player")
  1604.    return;
  1605.    
  1606.     player_run ();          // get out of any weapon firing states
  1607.  
  1608.     self.items = self.items - ( self.items & (IT_SHELLS | IT_NAILS | IT_ROCKETS | IT_CELLS) );
  1609.     
  1610.  
  1611.         if (self.dog_time)       // Dog stuff
  1612.         {
  1613.         self.currentammo = 0;
  1614.                 self.weaponmodel = "";
  1615.         self.weaponframe = 0;
  1616.         }
  1617.         else if (self.weapon == IT_AXE)
  1618.     {
  1619.         self.currentammo = 0;
  1620.         self.weaponmodel = "progs/v_axe.mdl";
  1621.         self.weaponframe = 0;
  1622.     }
  1623.     else if (self.weapon == IT_SHOTGUN)
  1624.     {
  1625.         self.currentammo = self.ammo_shells;
  1626.         self.weaponmodel = "progs/v_shot.mdl";
  1627.         self.weaponframe = 0;
  1628.         self.items = self.items | IT_SHELLS;
  1629.     }
  1630.         else if (self.weapon == IT_SNIPERGUN)
  1631.     {
  1632.         self.currentammo = self.ammo_shells;
  1633.         self.weaponmodel = "progs/v_shot.mdl";
  1634.         self.weaponframe = 0;
  1635.         self.items = self.items | IT_SHELLS;
  1636.     }
  1637.     else if (self.weapon == IT_SUPER_SHOTGUN)
  1638.     {
  1639.         self.currentammo = self.ammo_shells;
  1640.         self.weaponmodel = "progs/v_shot2.mdl";
  1641.         self.weaponframe = 0;
  1642.         self.items = self.items | IT_SHELLS;
  1643.     }
  1644.         else if (self.weapon == IT_FIREBALLGUN || self.weapon == IT_FLAMETHROWER)
  1645.     {
  1646.                 self.currentammo = self.ammo_shells;
  1647.         self.weaponmodel = "progs/v_rock.mdl";
  1648.         self.weaponframe = 0;
  1649.                 self.items = self.items | IT_CELLS;
  1650.     }
  1651.     else if (self.weapon == IT_NAILGUN)
  1652.     {
  1653.         self.currentammo = self.ammo_nails;
  1654.         self.weaponmodel = "progs/v_nail.mdl";
  1655.         self.weaponframe = 0;
  1656.         self.items = self.items | IT_NAILS;
  1657.     }
  1658.     else if (self.weapon == IT_SUPER_NAILGUN)
  1659.     {
  1660.         self.currentammo = self.ammo_nails;
  1661.         self.weaponmodel = "progs/v_nail2.mdl";
  1662.         self.weaponframe = 0;
  1663.         self.items = self.items | IT_NAILS;
  1664.     }
  1665.         else if (self.weapon == IT_GRENADE_LAUNCHER)
  1666.     {
  1667.         self.currentammo = self.ammo_rockets;
  1668.         self.weaponmodel = "progs/v_rock.mdl";
  1669.         self.weaponframe = 0;
  1670.         self.items = self.items | IT_ROCKETS;
  1671.     }
  1672.         else if (self.weapon == IT_PIPE_LAUNCHER)
  1673.     {
  1674.         self.currentammo = self.ammo_rockets;
  1675.                 self.weaponmodel = "progs/v_pipe.mdl";
  1676.         self.weaponframe = 0;
  1677.         self.items = self.items | IT_ROCKETS;
  1678.     }
  1679.         else if (self.weapon == IT_ROCKET_LAUNCHER)
  1680.         {
  1681.         self.currentammo = self.ammo_rockets;
  1682.         self.weaponmodel = "progs/v_rock2.mdl";
  1683.         self.weaponframe = 0;
  1684.         self.items = self.items | IT_ROCKETS;
  1685.     }
  1686.         else if (self.weapon == IT_RAPID_LAUNCHER)
  1687.         {
  1688.         self.currentammo = self.ammo_rockets;
  1689.         self.weaponmodel = "progs/v_rock2.mdl";
  1690.         self.weaponframe = 0;
  1691.         self.items = self.items | IT_ROCKETS;
  1692.     }
  1693.         else if (self.weapon == IT_SPREAD_LAUNCHER)
  1694.         {
  1695.         self.currentammo = self.ammo_rockets;
  1696.         self.weaponmodel = "progs/v_rock2.mdl";
  1697.         self.weaponframe = 0;
  1698.         self.items = self.items | IT_ROCKETS;
  1699.         }
  1700.         else if (self.weapon == IT_HOME_LAUNCHER)
  1701.         {
  1702.         self.currentammo = self.ammo_rockets;
  1703.         self.weaponmodel = "progs/v_rock2.mdl";
  1704.         self.weaponframe = 0;
  1705.         self.items = self.items | IT_ROCKETS;
  1706.     }
  1707.         else if (self.weapon == IT_LASERGUN)
  1708.     {
  1709.         self.currentammo = self.ammo_cells;
  1710.                 self.weaponmodel = "progs/g_laser.mdl";
  1711.         self.weaponframe = 0;
  1712.         self.items = self.items | IT_CELLS;
  1713.         }
  1714.     else if (self.weapon == IT_LIGHTNING)
  1715.     {
  1716.         self.currentammo = self.ammo_cells;
  1717.         self.weaponmodel = "progs/v_light.mdl";
  1718.         self.weaponframe = 0;
  1719.         self.items = self.items | IT_CELLS;
  1720.         }
  1721.         else
  1722.     {
  1723.         self.currentammo = 0;
  1724.         self.weaponmodel = "";
  1725.         self.weaponframe = 0;
  1726.     }
  1727. };
  1728.  
  1729. float() W_BestWeapon =
  1730. {
  1731.     local   float   it;
  1732.     
  1733.     it = self.items;
  1734.  
  1735.     if(self.ammo_cells >= 1 && (it & IT_LIGHTNING) )
  1736.         return IT_LIGHTNING;
  1737.     else if(self.ammo_nails >= 2 && (it & IT_SUPER_NAILGUN) )
  1738.         return IT_SUPER_NAILGUN;
  1739.     else if(self.ammo_shells >= 2 && (it & IT_SUPER_SHOTGUN) )
  1740.         return IT_SUPER_SHOTGUN;
  1741.     else if(self.ammo_nails >= 1 && (it & IT_NAILGUN) )
  1742.         return IT_NAILGUN;
  1743.     else if(self.ammo_shells >= 1 && (it & IT_SHOTGUN) )
  1744.         return IT_SHOTGUN;
  1745.         else if (self.items & IT_AXE)
  1746.                 return IT_AXE;
  1747.         return IT_SHOTGUN;
  1748. };
  1749.  
  1750. float() W_CheckNoAmmo =
  1751. {
  1752. if (self.weapon == IT_AXE)
  1753.         return TRUE;
  1754.  
  1755. else if (self.weapon == IT_SNIPERGUN && self.currentammo > 3)
  1756.         return TRUE;
  1757.  
  1758. else if (self.weapon == IT_FIREBALLGUN && self.currentammo > 1)
  1759.         return TRUE;
  1760.  
  1761. else if (self.weapon == IT_HOME_LAUNCHER && self.currentammo > 9)
  1762.         return TRUE;
  1763.  
  1764. else if (self.weapon == IT_SPREAD_LAUNCHER && self.currentammo > 4)
  1765.         return TRUE;
  1766.  
  1767. else if (self.currentammo > 0)
  1768.         return TRUE;
  1769.  
  1770.         self.weapon = W_BestWeapon ();
  1771.  
  1772.     W_SetCurrentAmmo ();
  1773.     
  1774. // drop the weapon down
  1775.     return FALSE;
  1776. };
  1777.  
  1778. /*
  1779. ============
  1780. W_Attack
  1781.  
  1782. An attack impulse can be triggered now
  1783. ============
  1784. */
  1785. void()  player_axe1;
  1786. void()  player_axeb1;
  1787. void()  player_axec1;
  1788. void()  player_axed1;
  1789. void()  player_shot1;
  1790. void()  player_nail1;
  1791. void()  player_light1;
  1792. void()  player_rocket1;
  1793. void()  play_dog_atta1;
  1794.  
  1795. void() W_Attack =
  1796. {
  1797.         local   float   r;
  1798.         local vector dir;
  1799.  
  1800.         if (self.dog_time)       // Dog stuff
  1801.         {
  1802.                 self.attack_finished = time + 1;
  1803.                 play_dog_atta1();
  1804.                 return;
  1805.         }
  1806.  
  1807.         if ((!W_CheckNoAmmo ())||(self.isfeign))
  1808.         return;
  1809.  
  1810.     makevectors     (self.v_angle);                 // calculate forward angle for velocity
  1811.     self.show_hostile = time + 1;   // wake monsters up
  1812.  
  1813.         if (self.weapon == IT_AXE)
  1814.     {
  1815.                 if (self.follow == 1)
  1816.                         sound (self, CHAN_WEAPON, "weapons/ax1.wav", 1, ATTN_NORM);
  1817.         r = random();
  1818.         if (r < 0.25)
  1819.             player_axe1 ();
  1820.         else if (r<0.5)
  1821.             player_axeb1 ();
  1822.         else if (r<0.75)
  1823.             player_axec1 ();
  1824.         else
  1825.             player_axed1 ();
  1826.                 if (self.follow == 1)
  1827.                         self.attack_finished = time + 0.5;
  1828.     }
  1829.     else if (self.weapon == IT_SHOTGUN)
  1830.     {
  1831.         player_shot1 ();
  1832.                 sound (self, CHAN_WEAPON, "weapons/guncock.wav", 1, ATTN_NORM); 
  1833.                 self.punchangle_x = -2;
  1834.                 self.currentammo = self.ammo_shells = self.ammo_shells - 1;
  1835.                 dir = aim (self, 100000);
  1836.                 FireBullets (6, dir, '0.04 0.04 0');
  1837.                 SpawnShell ();
  1838.         self.attack_finished = time + 0.5;
  1839.     }
  1840.         else if (self.weapon == IT_SNIPERGUN)
  1841.     {
  1842.                 if (self.currentammo < 4)
  1843.                 {
  1844.                 sprint(self,"Requires 4 shells\n");
  1845.                 return;
  1846.                 }
  1847.         player_shot1 ();
  1848.                 sound (self ,CHAN_WEAPON, "weapons/shotgn2.wav", 1, ATTN_NORM); 
  1849.                 self.punchangle_x = -10;
  1850.                 self.currentammo = self.ammo_shells = self.ammo_shells - 4;
  1851.                 dir = aim (self, 1000000);
  1852.                 FireBullets (20, dir, '0 0 0');
  1853.                 SpawnShell ();
  1854.                 self.attack_finished = time + 2;
  1855.     }
  1856.     else if (self.weapon == IT_SUPER_SHOTGUN)
  1857.     {
  1858.                 if (self.currentammo == 1)
  1859.                 {
  1860.                 self.weapon = IT_SHOTGUN;
  1861.                 W_Attack();
  1862.         return;
  1863.                 }
  1864.         player_shot1 ();
  1865.     sound (self ,CHAN_WEAPON, "weapons/shotgn2.wav", 1, ATTN_NORM); 
  1866.     self.punchangle_x = -4;
  1867.     self.currentammo = self.ammo_shells = self.ammo_shells - 2;
  1868.     dir = aim (self, 100000);
  1869.     FireBullets (14, dir, '0.14 0.08 0');
  1870.         SpawnShell ();
  1871.         SpawnShell ();
  1872.         self.attack_finished = time + 0.7;
  1873.     }
  1874.     else if (self.weapon == IT_NAILGUN)
  1875.     {
  1876.         player_nail1 ();
  1877.     }
  1878.     else if (self.weapon == IT_SUPER_NAILGUN)
  1879.     {
  1880.         player_nail1 ();
  1881.     }
  1882.     else if (self.weapon == IT_GRENADE_LAUNCHER)
  1883.     {
  1884.         player_rocket1();
  1885.         W_FireGrenade();
  1886.         self.attack_finished = time + 0.6;
  1887.     }
  1888.         else if (self.weapon == IT_PIPE_LAUNCHER)
  1889.     {
  1890.         player_rocket1();
  1891.                 W_FireGrenade();
  1892.         self.attack_finished = time + 0.6;
  1893.     }
  1894.     else if (self.weapon == IT_ROCKET_LAUNCHER)
  1895.     {
  1896.         player_rocket1();
  1897.                 self.currentammo = self.ammo_rockets = self.ammo_rockets - 1;
  1898.                 sound (self, CHAN_WEAPON, "weapons/sgun1.wav", 1, ATTN_NORM);
  1899.                 self.punchangle_x = -2;
  1900.                 dir = aim(self, 1000);
  1901.                 W_FireRocket2(dir,self,"rocket");
  1902.         self.attack_finished = time + 0.8;
  1903.     }
  1904.         else if (self.weapon == IT_FIREBALLGUN)
  1905.     {
  1906.         player_rocket1();
  1907.                 FireBall(1,'0 0 0');
  1908.         self.attack_finished = time + 0.8;
  1909.     }
  1910.         else if (self.weapon == IT_FLAMETHROWER)
  1911.     {
  1912.                 player_shot1();
  1913.                 W_FireFlame();
  1914.                 self.attack_finished = time + 0.03;
  1915.     }
  1916.         else if (self.weapon == IT_HOME_LAUNCHER && (self.ammo_rockets > 9))
  1917.     {
  1918.                 player_rocket1();
  1919.                 self.currentammo = self.ammo_rockets = self.ammo_rockets - 10;
  1920.                 sound (self, CHAN_WEAPON, "weapons/sgun1.wav", 1, ATTN_NORM);
  1921.                 self.punchangle_x = -2;
  1922.                 dir = aim(self, 1000);
  1923.                 W_FireRocket2(dir,self,"homerocket");
  1924.                 self.attack_finished = time + 1.2;
  1925.     }
  1926.         else if (self.weapon == IT_RAPID_LAUNCHER)
  1927.     {
  1928.         player_rocket1();
  1929.                 if (self.ammo_rockets > 0)
  1930.                 {
  1931.                         if (random () > 0.4)
  1932.                                 W_FireSpread("spreadrocket");
  1933.                         else
  1934.                                 W_FireSpread("homespread");
  1935.                 }
  1936.                 self.feigning = self.feigning + 1;
  1937.                 if (self.feigning > 9)
  1938.                         {
  1939.                         self.feigning = 0;
  1940.                         self.attack_finished = time + 2;
  1941.                         }
  1942.                 else self.attack_finished = time + 0.1;
  1943.         }
  1944.         else if (self.weapon == IT_SPREAD_LAUNCHER)
  1945.     {
  1946.         player_rocket1();
  1947.                 W_FireSpread("spreadrocket");
  1948.                 if (self.ammo_rockets > 0)
  1949.                 W_FireSpread("spreadrocket");
  1950.                 if (self.ammo_rockets > 0)
  1951.                 W_FireSpread("spreadrocket");
  1952.                 if (self.ammo_rockets > 0)
  1953.                 W_FireSpread("spreadrocket");
  1954.                 if (self.ammo_rockets > 0)
  1955.                 W_FireSpread("spreadrocket");
  1956.                 self.attack_finished = time + 1;
  1957.     }
  1958.     else if (self.weapon == IT_LIGHTNING)
  1959.     {
  1960.         player_light1();
  1961.         self.attack_finished = time + 0.1;
  1962.         sound (self, CHAN_AUTO, "weapons/lstart.wav", 1, ATTN_NORM);
  1963.     }
  1964.         else if (self.weapon == IT_LASERGUN)         //SHYFT ADD
  1965.     {
  1966.         player_shot1();
  1967.        self.effects = self.effects | EF_MUZZLEFLASH;
  1968.         self.currentammo = self.ammo_cells = self.ammo_cells - 1;
  1969.         sound (self, CHAN_WEAPON, "enforcer/enfire.wav", 1, ATTN_NORM);
  1970.         dir = aim(self, 1000);
  1971.         PLaser(dir,self); 
  1972.         self.attack_finished = time + 0.2;
  1973.     }
  1974. };
  1975.  
  1976. /*
  1977. ============
  1978. W_ChangeWeapon
  1979.  
  1980. ============
  1981. */
  1982. void() W_ChangeWeapon =
  1983. {
  1984.         if (self.isfeign)       // experimental
  1985.                 return;
  1986.  
  1987.     local   float   it, am, fl;
  1988.     
  1989.     it = self.items;
  1990.     am = 0;
  1991.     
  1992.     if (self.impulse == 1)
  1993.     {
  1994.                 if (self.amtaxe < 1)
  1995.                         return;
  1996.                 fl = IT_AXE;
  1997.                 if (self.follow == 0)
  1998.                         {
  1999.                         self.follow = 1;
  2000.                         sprint(self,"Axe in Melee Mode\n");
  2001.                         }
  2002.                 else
  2003.                 {
  2004.                    self.follow = 0;
  2005.                    sprint(self,"Axe in Throwing Mode\n");
  2006.                 }
  2007.         }
  2008.     else if (self.impulse == 2)
  2009.     {
  2010.                 if (self.weapon == IT_SHOTGUN)
  2011.                 {
  2012.                 fl = IT_SNIPERGUN;
  2013.                 if (self.ammo_shells < 4)
  2014.                         am = 1;
  2015.                 else if (self.items & fl)
  2016.                 {
  2017.                 sound (self, CHAN_WEAPON, "weapons/pkup.wav", 1, ATTN_NORM);
  2018.                 centerprint (self,"Sniper Mode\n");
  2019.                 }
  2020.                 }
  2021.                 else
  2022.                 {
  2023.                 fl = IT_SHOTGUN;
  2024.                 if (self.ammo_shells < 1)
  2025.             am = 1;
  2026.                 else if (self.items & fl)
  2027.                 {
  2028.                 sound (self, CHAN_WEAPON, "weapons/pkup.wav", 1, ATTN_NORM);
  2029.                 centerprint (self,"Shotgun Mode\n");
  2030.                 }
  2031.                 }
  2032.     }
  2033.     else if (self.impulse == 3)
  2034.     {
  2035.         fl = IT_SUPER_SHOTGUN;
  2036.         if (self.ammo_shells < 2)
  2037.             am = 1;
  2038.     }               
  2039.         else if (self.impulse == 4)
  2040.     {
  2041.                     if (self.items & IT_GRENADE_LAUNCHER)
  2042.                     if(self.weapon == IT_FLAMETHROWER)    
  2043.                     {
  2044.                         fl = IT_FIREBALLGUN;
  2045.                         if (self.ammo_shells < 2)
  2046.                                 am = 1;
  2047.                         else
  2048.                         {
  2049.                                 sound (self, CHAN_WEAPON, "weapons/pkup.wav", 1, ATTN_NORM);
  2050.                                 centerprint (self,"Fireballs Ready\n");
  2051.                         }
  2052.                     }
  2053.                     else
  2054.                     {
  2055.                         fl = IT_FLAMETHROWER;
  2056.                         if (self.ammo_shells < 1)
  2057.                                 am = 1;
  2058.                         else
  2059.                         {
  2060.                                 sound (self, CHAN_WEAPON, "weapons/pkup.wav", 1, ATTN_NORM);
  2061.                                 centerprint (self,"Flamethrower Ready\n");
  2062.                         }
  2063.                     }
  2064.     }
  2065.     else if (self.impulse == 5)
  2066.     {
  2067.                 if (self.weapon == IT_NAILGUN)
  2068.                 {
  2069.                 fl = IT_SUPER_NAILGUN;
  2070.                 if (self.ammo_nails < 1)
  2071.                         am = 1;
  2072.                 else if (self.items & fl)
  2073.                         sound (self, CHAN_WEAPON, "weapons/pkup.wav", 1, ATTN_NORM);
  2074.                 }
  2075.                 else
  2076.                 {
  2077.                 fl = IT_NAILGUN;
  2078.                 if (!(self.items & fl))
  2079.                         {
  2080.                         fl = IT_SUPER_NAILGUN;
  2081.                         if (self.ammo_nails < 2)
  2082.                                 am = 1;
  2083.                         }
  2084.                 }
  2085.     }
  2086.     else if (self.impulse == 6)
  2087.     {
  2088.                 if (self.weapon == IT_GRENADE_LAUNCHER)
  2089.                 {
  2090.                         fl = IT_PIPE_LAUNCHER;
  2091.                         if (self.ammo_rockets < 1)
  2092.                                 am = 1;
  2093.                         else if (self.items & fl)
  2094.                         {
  2095.                         sound (self, CHAN_WEAPON, "weapons/pkup.wav", 1, ATTN_NORM);
  2096.                         centerprint (self,"PipeBomb Fire Mode\n");
  2097.                         }
  2098.                 }
  2099.                 else
  2100.                 {
  2101.                         fl = IT_GRENADE_LAUNCHER;
  2102.                         if (self.ammo_rockets < 1)
  2103.                                am = 1;
  2104.                         else if (self.items & fl)
  2105.                         {
  2106.                         sound (self, CHAN_WEAPON, "weapons/pkup.wav", 1, ATTN_NORM);
  2107.                         centerprint (self,"Grenade Fire Mode\n");
  2108.                         }
  2109.                 }
  2110.  
  2111.     }
  2112.     else if (self.impulse == 7)
  2113.     {
  2114.                 if (self.weapon == IT_ROCKET_LAUNCHER)
  2115.                 {
  2116.                         fl = IT_RAPID_LAUNCHER;
  2117.                         if (self.ammo_rockets < 1)
  2118.                                am = 1;
  2119.                         else if (self.items & fl)
  2120.                         {
  2121.                         sound (self, CHAN_WEAPON, "weapons/pkup.wav", 1, ATTN_NORM);
  2122.                         centerprint (self,"Rapid Fire Mode\n");
  2123.                         }
  2124.                 }
  2125.                 else if (self.weapon == IT_RAPID_LAUNCHER)
  2126.                 {
  2127.                         fl = IT_SPREAD_LAUNCHER;
  2128.                         if (self.ammo_rockets < 5)
  2129.                                am = 1;
  2130.                         else if (self.items & fl)
  2131.                         {
  2132.                         sound (self, CHAN_WEAPON, "weapons/pkup.wav", 1, ATTN_NORM);
  2133.                         centerprint (self,"Spread Fire Mode\n");
  2134.                         }
  2135.                 }
  2136.                 else if (self.weapon == IT_SPREAD_LAUNCHER)
  2137.                 {
  2138.                         fl = IT_HOME_LAUNCHER;
  2139.                         if (self.ammo_rockets < 10)
  2140.                                 am = 1;
  2141.                         else if (self.items & fl)
  2142.                         {
  2143.                         sound (self, CHAN_WEAPON, "weapons/pkup.wav", 1, ATTN_NORM);
  2144.                         centerprint (self,"Homing Fire Mode\n");
  2145.                         } 
  2146.                 }
  2147.                 else
  2148.                 {
  2149.                         fl = IT_ROCKET_LAUNCHER;
  2150.                         if (self.ammo_rockets < 1)
  2151.                                 am = 1;
  2152.                         else if (self.items & fl)
  2153.                         {
  2154.                         sound (self, CHAN_WEAPON, "weapons/pkup.wav", 1, ATTN_NORM);
  2155.                         centerprint (self,"Normal Fire Mode\n");
  2156.                         } 
  2157.                 }
  2158.      }
  2159.     else if (self.impulse == 8)
  2160.     {
  2161.                 if (self.weapon == IT_LASERGUN)
  2162.                 {
  2163.                         fl = IT_LIGHTNING;
  2164.                         if (self.ammo_cells < 1)
  2165.                                 am = 1;
  2166.                         else if (self.items & fl)
  2167.                                 {
  2168.                                         sound (self, CHAN_WEAPON, "weapons/pkup.wav", 1, ATTN_NORM);
  2169.                                 }
  2170.                 }
  2171.                 else
  2172.                 {
  2173.                         if (self.items & IT_LIGHTNING)
  2174.                         {
  2175.                         fl = IT_LASERGUN;
  2176.                         if (self.ammo_cells < 1)
  2177.                                 am = 1;
  2178.                         }
  2179.                 }
  2180.     }
  2181.  
  2182.     self.impulse = 0;
  2183.     
  2184.     if (!(self.items & fl))
  2185.     {       // don't have the weapon or the ammo
  2186.                 sprint (self, "You don't have that weapon.\n");
  2187.         return;
  2188.     }
  2189.     
  2190.     if (am)
  2191.     {       // don't have the ammo
  2192.         sprint (self, "not enough ammo.\n");
  2193.         return;
  2194.     }
  2195.  
  2196. //
  2197. // set weapon, set ammo
  2198. //
  2199.     self.weapon = fl;               
  2200.     W_SetCurrentAmmo ();
  2201. };
  2202.  
  2203. /*
  2204. ============
  2205. CheatCommand
  2206. ============
  2207. */
  2208. void() CheatCommand =
  2209. {
  2210.         if (deathmatch || coop)
  2211.         return;
  2212.  
  2213.     self.ammo_rockets = 100;
  2214.     self.ammo_nails = 200;
  2215.     self.ammo_shells = 100;
  2216.     self.items = self.items | 
  2217.         IT_AXE |
  2218.         IT_SHOTGUN |
  2219.         IT_SUPER_SHOTGUN |
  2220.         IT_NAILGUN |
  2221.         IT_SUPER_NAILGUN |
  2222.         IT_GRENADE_LAUNCHER |
  2223.         IT_ROCKET_LAUNCHER |
  2224.                 IT_PIPE_LAUNCHER |
  2225.                 IT_FIREBALLGUN |
  2226.                 IT_SNIPERGUN |
  2227.                 IT_LASERGUN |
  2228.                 IT_HOME_LAUNCHER |
  2229.                 IT_SPREAD_LAUNCHER |
  2230.                 IT_RAPID_LAUNCHER |
  2231.         IT_KEY1 | IT_KEY2;
  2232.  
  2233.     self.ammo_cells = 200;
  2234.     self.items = self.items | IT_LIGHTNING;
  2235.  
  2236.     self.weapon = IT_ROCKET_LAUNCHER;
  2237.     self.impulse = 0;
  2238.         self.exp = 900000;
  2239.         self.init_mana = time - 900;
  2240.         sprint(self,"Full Mana\n");
  2241.     W_SetCurrentAmmo ();
  2242. };
  2243.  
  2244. /*
  2245. ============
  2246. CycleWeaponCommand- temporarily deactivated
  2247.  
  2248. Go to the next weapon with ammo
  2249. ============
  2250. void() CycleWeaponCommand =
  2251. {
  2252.     local   float   it, am;
  2253.     
  2254.     it = self.items;
  2255.     self.impulse = 0;
  2256.     
  2257.     while (1)
  2258.     {
  2259.         am = 0;
  2260.  
  2261.                 if (self.weapon == IT_LIGHTNING)
  2262.                 {
  2263.                         self.weapon = IT_AXE;
  2264.                         centerprint (self,"Axe\n");
  2265.         }
  2266.         else if (self.weapon == IT_AXE)
  2267.         {
  2268.             self.weapon = IT_SHOTGUN;
  2269.             if (self.ammo_shells < 1)
  2270.                 am = 1;
  2271.                         else
  2272.                         centerprint (self,"Shotgun\n");
  2273.         }
  2274.         else if (self.weapon == IT_SHOTGUN)
  2275.         {
  2276.                         self.weapon = IT_SNIPERGUN;
  2277.                         if (self.ammo_shells < 4)
  2278.                 am = 1;
  2279.                         else
  2280.                         centerprint (self,"Shotgun, Sniper Mode\n");
  2281.         }
  2282.                 else if (self.weapon == IT_SNIPERGUN)
  2283.         {
  2284.             self.weapon = IT_SUPER_SHOTGUN;
  2285.             if (self.ammo_shells < 2)
  2286.                 am = 1;
  2287.                         else if (it & IT_SUPER_SHOTGUN)
  2288.                                 centerprint (self,"Double Barrelled Shotgun\n");
  2289.         }               
  2290.                 else if (self.weapon == IT_SUPER_SHOTGUN && (it & IT_GRENADE_LAUNCHER))
  2291.         {
  2292.                         self.weapon = IT_FLAMETHROWER;
  2293.                         if (self.ammo_shells < 1)
  2294.                 am = 1;
  2295.                         else centerprint (self,"Flamethrower\n");
  2296.         }
  2297.                 else if (self.weapon == IT_FIREBALLGUN || self.weapon == IT_FLAMETHROWER)
  2298.         {
  2299.             self.weapon = IT_NAILGUN;
  2300.             if (self.ammo_nails < 1)
  2301.                 am = 1;
  2302.                         else if (it & IT_NAILGUN)
  2303.                                 centerprint (self,"Nailgun\n");
  2304.         }
  2305.                 else if (self.weapon == IT_NAILGUN)
  2306.         {
  2307.             self.weapon = IT_SUPER_NAILGUN;
  2308.             if (self.ammo_nails < 2)
  2309.                 am = 1;
  2310.                         else if (it & IT_SUPER_NAILGUN)
  2311.                                 centerprint (self,"Super Nailgun\n");
  2312.         }
  2313.         else if (self.weapon == IT_SUPER_NAILGUN)
  2314.         {
  2315.             self.weapon = IT_GRENADE_LAUNCHER;
  2316.                         if (self.ammo_rockets < 1)
  2317.                 am = 1;
  2318.                         else if (it & IT_GRENADE_LAUNCHER)
  2319.                                 centerprint (self,"Grenade Launcher\n");
  2320.         }
  2321.                 else if ((self.weapon > 15) && (self.weapon < 32))
  2322.         {
  2323.                         self.weapon = IT_ROCKET_LAUNCHER;
  2324.                         if (self.ammo_rockets < 1)
  2325.                                 am = 1;
  2326.                         else if (it & IT_ROCKET_LAUNCHER)
  2327.                                 centerprint (self,"Rocket Launcher\n");
  2328.                 }
  2329.                 else if ((self.weapon > 31) && (self.weapon < 64) && (it & IT_LIGHTNING))
  2330.         {
  2331.                         self.weapon = IT_LASERGUN;
  2332.             if (self.ammo_cells < 1)
  2333.                 am = 1;
  2334.                         else if (it & IT_LIGHTNING)
  2335.                                 centerprint (self,"Laser Gun\n");
  2336.         }
  2337.                 else if (self.weapon == IT_LASERGUN)
  2338.         {
  2339.                         self.weapon = IT_LIGHTNING;
  2340.             if (self.ammo_cells < 1)
  2341.                 am = 1;
  2342.                         else if (it & IT_LIGHTNING)
  2343.                                centerprint (self,"Thunderbolt\n");
  2344.                 }
  2345.     
  2346.                 if ((self.items & self.weapon) && am == 0)
  2347.                 {                              
  2348.             W_SetCurrentAmmo ();
  2349.             return;
  2350.         }
  2351.     }
  2352. };
  2353. */
  2354. /*
  2355. ============
  2356. ServerflagsCommand
  2357.  
  2358. Just for development
  2359. ============
  2360. */
  2361. void() ServerflagsCommand =
  2362. {
  2363.     serverflags = serverflags * 2 + 1;
  2364. };
  2365.  
  2366. /*
  2367. ============
  2368. ImpulseCommands
  2369.  
  2370. ============
  2371. */
  2372. void() ImpulseCommands =
  2373. {
  2374. local string printnum;
  2375.         if (self.impulse == 150)
  2376.                 if (self.dog_time)
  2377.                       return;
  2378.                 else feign(self);
  2379.         else if (self.impulse == 30 && self.newholo.active)
  2380.                 CheckHoloCommand();
  2381.         else if (self.impulse == 31)
  2382.                 HoloCam(self);
  2383.         else if (self.impulse == 32)
  2384.                 if (self.newholo.active == TRUE)
  2385.                 DetHolo();
  2386.                 else
  2387.                 {
  2388.                 sound (self, CHAN_WEAPON, "doors/basetry.wav", 1 , ATTN_NORM);
  2389.                 sprint(self,"Holograph not active!\n");
  2390.                 }
  2391.         else if (self.impulse == 33)
  2392.                 if (self.newholo.active == TRUE)
  2393.                 feign(self.newholo);
  2394.                 else
  2395.                 {
  2396.                 sound (self, CHAN_WEAPON, "doors/basetry.wav", 1 , ATTN_NORM);
  2397.                 sprint(self,"Holograph not active!\n");
  2398.                 }
  2399.         else if(self.isfeign)
  2400.                 return;
  2401.         else if (self.impulse == 40 && self.teleeyes.active)
  2402.                 TeleEyes();
  2403.         else if(self.impulse == 120)
  2404.           self.Kick_em = 1;
  2405.     else
  2406.           self.Kick_em = 0;
  2407.  
  2408.         if (self.impulse >= 1 && self.impulse <= 8)
  2409.         W_ChangeWeapon ();
  2410.  
  2411.         else if (self.impulse == 9)
  2412.         CheatCommand ();
  2413. //        else if (self.impulse == 10)
  2414. //               CycleWeaponCommand ();
  2415.         else if (self.impulse == 11)
  2416.         ServerflagsCommand ();
  2417.         else if (self.impulse == 20||self.impulse == 21)
  2418.                 DropBackpack();
  2419.         else if (self.impulse == 22)
  2420.                 Duck();
  2421.         else if (self.impulse == 140 || self.impulse == 142)
  2422.                 {
  2423.                 self.skin = self.skin - (self.impulse - 141);
  2424.                 if (self.skin < 0) self.skin = 23;
  2425.                 else if (self.skin > 23) self.skin = 0;
  2426.                 printnum=ftos(self.skin+1);
  2427.                 centerprint(self,printnum);
  2428.                 }
  2429.         else if (self.impulse == 50)
  2430.                 CycleSpell(-1);
  2431.         else if (self.impulse == 51)
  2432.                 CycleSpell(1);
  2433.         else if (self.impulse == 52)
  2434.                 {
  2435.                 if (time < self.alivetime)
  2436.                         {
  2437.                         self.impulse = 0;
  2438.                         return;
  2439.                         }
  2440.                 self.mana = rint(time - self.init_mana);
  2441.                 if (self.mana > self.exp/1000)
  2442.                         self.mana = self.exp/1000;
  2443.                 if (self.mana >= self.spell)
  2444.                         if (self.silencetime < time)
  2445.                                 Cast();
  2446.                         else
  2447.                         {
  2448.                         sprint(self,"You have been silenced, you may cast a spell in: ");
  2449.                         printnum=ftos(rint(self.silencetime-time));
  2450.                         sprint(self,printnum);
  2451.                         sprint(self," seconds\n");
  2452.                         }
  2453.                 else
  2454.                 {
  2455.                 sprint(self,"Not enough mana!\n");
  2456.                 sprint(self,"Mana: ");
  2457.                 printnum=ftos(self.mana);
  2458.                 sprint(self,printnum);
  2459.                 sprint(self,", this spell needs: ");
  2460.                 printnum=ftos(self.spell);
  2461.                 sprint(self,printnum);
  2462.                 sprint(self,"\n");
  2463.                 }
  2464.                 }
  2465.         else if (self.impulse == 53)
  2466.                 PrintSpellName();
  2467.         else if(self.impulse == 62)
  2468.       DetPipeBombs();
  2469.         else if(self.impulse == 63)
  2470.       DisarmPipeBombs();
  2471.  
  2472.     self.impulse = 0;
  2473. };
  2474.  
  2475. void() PlayerTouch =
  2476. {
  2477.  if(other.takedamage != DAMAGE_AIM)
  2478.    return;
  2479.  if(self.Kick_em)
  2480. {   
  2481.  // boot them in the rear!
  2482.  if(other.classname == "player")    // only advertise player kicking
  2483.  {
  2484.   bprint(self.netname);
  2485.   bprint(" gives ");
  2486.   bprint(other.netname);
  2487.   bprint(" the boot.\n");
  2488.  }
  2489.  if (other.classname == "head"||other.classname == "player")
  2490.  {
  2491.  other.velocity_x = other.velocity_x + self.velocity_x*2;
  2492.  other.velocity_y = other.velocity_y + self.velocity_y*2;
  2493.  other.velocity_z = other.velocity_z + 300 + (random() * 200); //     add lift
  2494.  }
  2495.  else
  2496.  {
  2497.  other.velocity_x = other.velocity_x + self.velocity_x/2;
  2498.  other.velocity_y = other.velocity_y + self.velocity_y/2;
  2499.  other.velocity_z = other.velocity_z + 50 + (random() * 100); //     add lift
  2500.  if(other.controller==self)
  2501.          T_Damage (other, self, self, 1);
  2502.  else T_Damage (other, self, self, 3);
  2503.  }
  2504.  sound (self, CHAN_WEAPON, "weapons/kick.wav", 1, ATTN_NORM);
  2505.  if(other.flags & FL_ONGROUND)
  2506.    other.flags = other.flags - FL_ONGROUND;
  2507.    return;
  2508. }
  2509. if ((other.classname == "corpse" || other.classname == "head" || other.alive)&&(other.origin_z<self.origin_z - 20))
  2510.        {
  2511.        self.flags = self.flags + FL_ONGROUND;
  2512.        return;
  2513.        }
  2514. if(other.pausetime>time+5||other.nextthink>time+5||(other.controller==self&&other.classname!="throwaxe"))
  2515.         {
  2516.         other.velocity_y = self.velocity_y/3;
  2517.         other.velocity_x = self.velocity_x/3;
  2518.         other.velocity_z = other.velocity_z + 1;
  2519.         if(other.flags&FL_ONGROUND)
  2520.                 other.flags=other.flags-FL_ONGROUND;
  2521.         }
  2522. };
  2523. /*
  2524. ========
  2525. SuperDamageSound
  2526.  
  2527. Plays sound if needed
  2528. ========
  2529. void() SuperDamageSound =
  2530. {
  2531.     if (self.super_damage_finished > time)
  2532.     {
  2533.         if (self.super_sound < time)
  2534.         {
  2535.             self.super_sound = time + 1;
  2536.             sound (self, CHAN_BODY, "items/damage3.wav", 1, ATTN_NORM);
  2537.         }
  2538.     }
  2539.     return;
  2540. };
  2541. */
  2542.  
  2543. /*
  2544. ============
  2545. W_WeaponFrame
  2546.  
  2547. Called every frame so impulse events can be handled as well as possible
  2548. ============
  2549. */
  2550. void() W_WeaponFrame =
  2551. {
  2552.     if (time < self.attack_finished)
  2553.         return;
  2554.  
  2555.     ImpulseCommands ();
  2556.     
  2557. // check for attack
  2558.     if (self.button0)
  2559.     {
  2560. //                SuperDamageSound ();
  2561.         W_Attack ();
  2562.     }
  2563. };
  2564.  
  2565. // Throwing Axe
  2566. void() ThrowAxeThink =
  2567. {
  2568.  
  2569. if (self.active == 1)
  2570. {
  2571.         if(visible(self.controller))
  2572.         {
  2573.         if (self.effects == 0)
  2574.                 self.effects = 8;
  2575.         else if (self.effects == 8)
  2576.                 {
  2577.                 self.effects = 4;
  2578.                 sound(self, CHAN_WEAPON, "items/protect3.wav", 0.3, ATTN_NORM);
  2579.                 sprint(self.controller,"Mjolnir Beckons....\n");
  2580.                 self.aflag = self.aflag + 1;
  2581.                 }
  2582.         else if (self.effects == 4)
  2583.                 self.effects = 8;
  2584.         if (self.aflag > 32)
  2585.                 {
  2586.                         sound(self.controller, CHAN_ITEM, "weapons/pkup.wav", 1, ATTN_NORM);
  2587.                         self.controller.amtaxe = self.controller.amtaxe + 1;
  2588.                         self.controller.follow = 1;
  2589.                         self.controller.impulse = 1;
  2590.                         sprint(self.controller,"Mjolnir has magically returned\n");
  2591.                         MagicEffect(self.controller);
  2592.                         remove(self);
  2593.                 }
  2594.         }
  2595.         else self.effects = 0;
  2596.         self.nextthink = time + 0.5;
  2597. }
  2598. else
  2599. {
  2600.         if (self.active == -1)
  2601.         {
  2602.         local vector vtemp,dir;
  2603.           vtemp = self.controller.origin + '0 0 10';
  2604.           dir = normalize(vtemp - self.origin);
  2605.         if (self.watertype < -2)
  2606.              self.velocity = dir * 150;
  2607.         else self.velocity = dir * 375;
  2608.           self.angles = vectoangles(self.velocity);
  2609.         if (self.flags & FL_ONGROUND)// && self.follow == 0)
  2610.                 {
  2611.                    self.avelocity = '500 0 0';
  2612.                    self.flags = self.flags - FL_ONGROUND;
  2613. //                   self.follow = 1;
  2614.                 }
  2615.         }
  2616.         sound(self, CHAN_WEAPON, "weapons/woosh.wav", 0.3, ATTN_NORM);
  2617.         SpawnFlame(self.origin);
  2618.         self.nextthink = time + 0.2;
  2619. }
  2620.         if(self.controller.health<=0)
  2621.                 {
  2622.                 GrenadeExplode();
  2623.                 remove(self);
  2624.                 }
  2625. self.think = ThrowAxeThink;
  2626. };
  2627.  
  2628. void() AxeTouch =
  2629. {
  2630. local float clink;
  2631.   if (other == self.controller)
  2632.         {
  2633.                 if (self.active!=0||self.bloodloss<time)
  2634.                 {
  2635.                         sound(other, CHAN_ITEM, "weapons/pkup.wav", 1, ATTN_NORM);
  2636.                         other.amtaxe = other.amtaxe + 1;
  2637.                         other.follow = 1;
  2638.                         other.impulse = 1;
  2639.                         remove(self);
  2640.                         return;
  2641.                 }
  2642.                 else return;
  2643.         }
  2644.  
  2645.   else if (other.takedamage)
  2646.   {
  2647.       if(self.velocity != VEC_ORIGIN && other != self.controller)
  2648.         if (self.active < 1)  
  2649.         {
  2650.               spawn_touchblood(40);
  2651.               SpawnChunk(self.origin, self.velocity);
  2652.               other.punchangle_x = -20;
  2653.               self.enemy = other;  
  2654.               T_Damage(other, self, self.controller, 10);
  2655.               other.velocity_x = other.velocity_x + self.velocity_x*2;
  2656.               other.velocity_y = other.velocity_y + self.velocity_y*2;
  2657.               other.velocity_z = other.velocity_z + 100;
  2658.               other.flags = other.flags - FL_ONGROUND;
  2659.               self.classname = "axhit";
  2660.               SpawnFlame();
  2661.               self.classname = "throwaxe";
  2662.         }
  2663.         else if (other.classname == "player")
  2664.         {
  2665.                 sprint(self.controller,"Your axe was stolen by ");
  2666.                 sprint(self.controller,other.netname);
  2667.                 sprint(self.controller,"!\n");
  2668.                 sprint(other,"You got ");
  2669.                 sprint(other,self.controller.netname);
  2670.                 sprint(other,"'s axe!\n");
  2671.                 sound(other, CHAN_ITEM, "weapons/pkup.wav", 1, ATTN_NORM);
  2672.                 other.amtaxe = other.amtaxe + 1;
  2673.                 other.follow = 1;
  2674.                 other.impulse = 1;
  2675.                 remove(self);
  2676.         }  
  2677.   }
  2678.   else
  2679.   {
  2680.     clink = random() * FL_SWIM;
  2681.     if (clink <= 1) 
  2682.       sound(self, CHAN_WEAPON, "player/axhit2.wav", 1, ATTN_NORM);
  2683.     else
  2684.       sound(self, CHAN_WEAPON, "weapons/tink1.wav", 1, ATTN_NORM);
  2685.   }
  2686.  
  2687.   if (self.active < 1)
  2688.        if (visible(self.controller))
  2689.                self.active = -1;
  2690.        else
  2691.        {
  2692.        if (self.active != 1)
  2693.         sprint(self.controller,"You lost your axe!\n");
  2694.        self.active = 1;
  2695.        self.effects = 0;
  2696.        self.avelocity = '300 300 300';
  2697.        setsize(self, '-3 -3 -5', '3 3 3');
  2698.        self.movetype = MOVETYPE_BOUNCE;
  2699.        }
  2700. };
  2701.  
  2702.  
  2703. void() W_ThrowAxe =
  2704. {
  2705. local entity missile;
  2706.   sound(self, CHAN_WEAPON, "weapons/woosh.wav", 1, ATTN_NORM);
  2707.   missile = spawn();
  2708.   missile.owner = missile;
  2709.   missile.controller = self;
  2710.   missile.classname = "throwaxe";
  2711.   missile.movetype = MOVETYPE_FLYMISSILE;
  2712.   missile.solid = SOLID_BBOX;
  2713.   makevectors(self.v_angle);
  2714.   missile.velocity = aim(self, 10000);
  2715.   missile.angles = vectoangles(missile.velocity);
  2716.   if (self.waterlevel > 2)
  2717.         missile.velocity = missile.velocity * 300;
  2718.   else
  2719.         missile.velocity = missile.velocity * 750;
  2720.   missile.touch = AxeTouch;
  2721.   missile.health = 100000;
  2722.   missile.takedamage = DAMAGE_AIM;
  2723.   missile.th_die = T_MissileTouch;
  2724.   missile.nextthink = time;
  2725.   missile.bloodloss = time+2;
  2726.   missile.think = ThrowAxeThink;
  2727.   setmodel(missile, "progs/throwaxe.mdl");
  2728.   setsize(missile,'-1 -2 -4','1 2 4');
  2729. //  setsize(missile, VEC_ORIGIN, VEC_ORIGIN);
  2730.   setorigin(missile, self.origin + v_forward * FL_SWIM + '0 0 16');
  2731.   missile.avelocity = '-500 0 0';
  2732.   missile.active = 0;
  2733.   missile.effects = 4;
  2734.   self.amtaxe = self.amtaxe - 1;
  2735.   if (self.amtaxe < 1)
  2736.         {
  2737.           self.follow = -1;
  2738.           self.impulse = 2;
  2739.           W_ChangeWeapon();
  2740.         }
  2741. };
  2742.